[英]How to properly pass data to sibling component using VueJS?
比方说,我有CountrySelect
和CitySelect
,在CountrySelect
列出的所有国家和CitySelect
只列出的目前选定的国家的这些城市...
通过新选择的国家/地区的正确方法是什么? 正如我在vuejs文档中阅读的:
在Vue中,父子组件关系可以概括为道具下降,事件上升。 父级通过道具将数据传递给子级,而子级则通过事件将消息发送给父级。 让我们看看它们接下来如何工作。
因此,在这种情况下,我将检测到CountrySelect
内的选择框发生了changed
,并且触发了火灾事件以及一个国家对象。 然后, CountrySelect
的父组件将侦听此事件,然后在发生该事件时将更新其属性country
。 在父组件中“观察到”属性country
,更改其值将导致DOM更新,因此<city-select>
标记上称为country
HTML属性将发生更改。 但是然后我将如何检测CitySelect
组件的属性变化,因为我需要通过AJAX重新加载城市。 我认为把的country
性质在watch
对象CitySelect
但这并不似乎是一个完美的解决方案给我,它不会感觉做一刀吧...
<template>
<parent>
<country-select name="country_id" v-model="country"></country-select>
<city-select name="city_id" :country="country" v-model="city"></city-select>
</parent>
<template>
<script>
export default {
data: function() {
return {
country: null,
city: null,
};
}
}
</script>
我认为的另一种解决方法是是否在父级中执行以下操作:
this.$refs.citySelect.emit('countryChanged', this.country)
要么:
this.$refs.citySelect.countryChanged(this.country)
我不知道这两位是可能的...那么,什么是正确的方式CountrySelect
组件告诉给其兄弟组件CitySelect
更新城市列表...
通过将country
作为属性传递给CitySelect
组件,您已经在做您需要做的事情。 country
更改时,更改后的值将传递到CitySelect
组件。 您只需要确保CitySelect
组件知道更改即可。
这是一个工作示例。
console.clear() // Simulated service for retrieving cities by country const CityService = { cities: [ {id: 1, country: "USA", name: "New York"}, {id: 2, country: "USA", name: "San Francisco"}, {id: 3, country: "USA", name: "Boston"}, {id: 4, country: "USA", name: "Chicago"}, {id: 5, country: "England", name: "London"}, {id: 6, country: "England", name: "Bristol"}, {id: 7, country: "England", name: "Manchester"}, {id: 8, country: "England", name: "Leeds"}, ], getCities(country){ return new Promise((resolve, reject) => { setTimeout(() => resolve(this.cities.filter(city => city.country === country)), 250) }) } } Vue.component("CountrySelect",{ props: ["value"], template: ` <select v-model="selectedCountry"> <option v-for="country in countries" :value="country">{{country}}</option> </select> `, data(){ return { countries: ["USA", "England"] } }, computed:{ selectedCountry:{ get(){return this.value}, set(v){this.$emit('input', v)} } } }) Vue.component("CitySelect", { props: ["value", "country"], template: ` <select v-model="selectedCity"> <option v-for="city in cities" :value="city">{{city.name}}</option> </select> `, data(){ return { cities: [] } }, computed:{ selectedCity:{ get(){return this.value}, set(v){this.$emit('input', v)} } }, watch:{ country(newCountry){ // simulate an AJAX call to an external service CityService.getCities(newCountry).then(cities => this.cities = cities) } } }) new Vue({ el: "#app", data:{ country: null, city: null } })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script> <div id="app"> <country-select v-model="country"></country-select> <city-select :country="country" v-model="city"></city-select> <hr> Selected Country: {{country}} <br> Selected City: {{city}} </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.