本文介绍了如何使用 VueJS 将数据正确传递给兄弟组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
假设我有 CountrySelect
和 CitySelect
,其中在 CountrySelect
中列出了所有国家,而在 CitySelect
中是只列出了当前所选国家的那些城市...
通过新选择的国家/地区的正确方法是什么.正如我在 vuejs 文档中所读到的:
在Vue中,父子组件关系可以概括为props down,event up.父级通过 props 将数据传递给子级,子级通过事件向父级发送消息.接下来让我们看看它们是如何工作的.
所以在这种情况下,我会检测 CountrySelect
和触发事件 changed
内的选择框的变化,以及一个国家对象.然后CountrySelect
的父组件会监听这个事件,然后当它发生时更新它的属性country
.属性 country
在父组件中被观察到",改变其值会导致 DOM 更新,因此
标签上的 HTML 属性称为 country
会改变.但是,我将如何检测 CitySelect
组件的属性更改,因为我需要通过 AJAX 重新加载城市.我想将 country
属性放在 CitySelect
中的 watch
对象中,但这对我来说似乎不是一个优雅的解决方案,感觉并不奇怪正确的做法...
<country-select name="country_id" v-model="country"></country-select><city-select name="city_id" :country="country" v-model="city"></city-select></父母><模板><脚本>导出默认{数据:函数(){返回 {国家:空,城市:空,};}}
我认为的另一种方法是,如果在父级中做这样的事情:
this.$refs.citySelect.emit('countryChanged', this.country)
或:
this.$refs.citySelect.countryChanged(this.country)
我不知道这两个是否可能...那么 CountrySelect
组件告诉其兄弟组件 CitySelect
更新城市列表的正确方法是什么...
解决方案
通过将 country
作为属性传递给 CitySelect
组件,您已经em> 做你需要做的事.当country
改变时,改变的值将传递给CitySelect
组件.您只需要确保您的 CitySelect
组件知道这些更改.
这是一个工作示例.
console.clear()//按国家检索城市的模拟服务const CityService = {城市: [{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"},],获取城市(国家){返回新的承诺((解决,拒绝)=> {setTimeout(() => resolve(this.cities.filter(city => city.country === country)), 250)})}}Vue.component("国家选择",{道具:[价值"],模板:`<select v-model="selectedCountry"><option v-for="country in countries" :value="country">{{country}}</option></选择>`,数据(){返回 {国家:[美国",英国"]}},计算:{所选国家:{get(){return this.value},set(v){this.$emit('input', v)}}}})Vue.component("城市选择", {道具:[价值",国家"],模板:`<select v-model="selectedCity"><option v-for="城市中的城市" :value="city">{{city.name}}</option></选择>`,数据(){返回 {城市:[]}},计算:{所选城市:{get(){return this.value},set(v){this.$emit('input', v)}}},手表:{国家(新国家){//模拟对外部服务的 AJAX 调用CityService.getCities(newCountry).then(cities => this.cities =城市)}}})新的 Vue({el: "#app",数据:{国家:空,城市:空}})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script><div id="应用程序"><country-select v-model="country"></country-select><city-select :country="country" v-model="city"></city-select><小时>所选国家/地区:{{country}}
所选城市:{{city}}
Let's say I have CountrySelect
and CitySelect
, where in CountrySelect
are listed all countries and in CitySelect
are only listed those cities of currently selected country...
What would the proper way to pass newly selected country. As I have read in vuejs documentation:
So in this case, I would detect change of select box inside of CountrySelect
and fire event changed
and along with it a country object. Then the parent component of CountrySelect
would listen for this event and then when that happens will update its attribute country
. Attribute country
is "observed" in parent component and changing its value will cause for DOM to update, so HTML attribute on <city-select>
tag called country
would change. But then how would I detect property change of CitySelect
component, since I need to reload cities via AJAX. I think of putting country
property in watch
object in CitySelect
but that does not seems like an elegant solution to me, it doesn't feels quire right to do...
<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>
Other way around that I think is if do something like this in parent:
this.$refs.citySelect.emit('countryChanged', this.country)
or:
this.$refs.citySelect.countryChanged(this.country)
I do not know if these two are possible... So what would be the correct way for CountrySelect
component to tell to its sibling component CitySelect
to update cities list...
解决方案
By passing country
as a property to your CitySelect
component, you are already doing what you need to do. When country
changes, the changed value will be passed to the CitySelect
component. You simply need to make sure your CitySelect
component is aware of the changes.
Here is a working example.
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>
这篇关于如何使用 VueJS 将数据正确传递给兄弟组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!