假设我有 CountrySelect
和CitySelect
,在 CountrySelect
中列出了所有国家和 CitySelect
仅列出当前所选国家/地区的城市...
通过新选择的国家/地区的正确方法是什么。正如我在 vuejs 文档中读到的:
In Vue, the parent-child component relationship can be summarized as props down, events up. The parent passes data down to the child via props, and the child sends messages to the parent via events. Let’s see how they work next.
所以在这种情况下,我会检测CountrySelect
内选择框的变化和火灾事件changed
以及一个国家对象。然后是CountrySelect
的父组件将监听此事件,然后当发生这种情况时将更新其属性 country
。属性country
在父组件中被“观察到”,更改其值将导致 DOM 更新,因此 <city-select>
上的 HTML 属性标签名为 country
会改变的。但是我如何检测 CitySelect
的属性变化组件,因为我需要通过 AJAX 重新加载城市。我想把country
属性(property) 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>
关于javascript - 如何使用 VueJS 正确地将数据传递给同级组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48190694/