我们说我有CountrySelect
和CitySelect
,其中CountrySelect
列出了所有国家/地区,CitySelect
仅列出了当前所选国家/地区的城市...
通过新选择的国家/地区的正确方法是什么?正如我在vuejs文档中读到的那样:
在Vue中,父子组件关系可以概括为道具向下,事件向上。父母通过道具将数据传递给孩子,孩子通过事件向父母发送消息。让我们看看他们下一步的工作方式。
所以在这种情况下,我会检测CountrySelect
和火灾事件changed
内部的选择框的变化,以及国家对象。然后CountrySelect
的父组件将侦听此事件,然后在发生这种情况时将更新其属性country
。属性country
是&#34;观察到的&#34;在父组件中并更改其值将导致DOM更新,因此名为<city-select>
的{{1}}标记上的HTML属性将更改。但是,我如何检测country
组件的属性更改,因为我需要通过AJAX重新加载城市。我想将CitySelect
属性放在country
中的watch
对象中,但这对我来说似乎不是一个优雅的解决方案,它不会让人觉得这样做... ... / p>
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
更新城市列表的正确方法是什么......
答案 0 :(得分:3)
将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
}
})
&#13;
<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>
&#13;