繁体   English   中英

如何使用VueJS将数据正确传递给同级组件?

[英]How to properly pass data to sibling component using VueJS?

比方说,我有CountrySelectCitySelect ,在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM