clz*_*ola 2 javascript vue.js vuejs2
假设我有CountrySelect和CitySelect,其中CountrySelect列出了所有国家/地区,并且CitySelect仅列出了当前所选国家/地区的城市...
通过新选择的国家的正确方法是什么?正如我在 vuejs 文档中读到的:
\n\n\n\n\n在Vue中,父子组件关系可以概括为props down,events up。父级通过 props 将数据传递给子级,子级通过事件向父级发送消息。接下来让\xe2\x80\x99s看看它们是如何工作的。
\n
CountrySelect因此,在这种情况下,我将检测触发事件内部选择框的变化changed以及国家/地区对象。然后 的父组件CountrySelect将侦听此事件,然后当事件发生时将更新其属性country。属性country在父组件中被“观察到”,并且更改其值将导致 DOM 更新,因此<city-select>调用的标记上的 HTML 属性country将会更改。但是接下来我将如何检测CitySelect组件的属性更改,因为我需要通过 AJAX 重新加载城市。我考虑将country属性放入watch对象中CitySelect,但这对我来说似乎不是一个优雅的解决方案,感觉这样做不太正确......
<template>\n <parent>\n <country-select name="country_id" v-model="country"></country-select>\n <city-select name="city_id" :country="country" v-model="city"></city-select>\n </parent>\n<template>\n\n<script>\n export default {\n data: function() {\n return {\n country: null,\n city: null,\n };\n }\n }\n</script>\nRun Code Online (Sandbox Code Playgroud)\n\n我认为的另一种方法是,如果在父级中做这样的事情:
\n\nthis.$refs.citySelect.emit(\'countryChanged\', this.country)\nRun Code Online (Sandbox Code Playgroud)\n\n或者:
\n\nthis.$refs.citySelect.countryChanged(this.country)\nRun Code Online (Sandbox Code Playgroud)\n\n我不知道这两个是否可能...那么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
}
})Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3332 次 |
| 最近记录: |