Vue.js 是一款流行的前端框架,用于构建用户界面。在开发 web 应用时,有时我们需要实现省市区三联动的下拉选择功能,即选择省份后,市的选择会根据省份动态更新,选择市后,区的选择也会随之更新。本文将详细介绍如何在 Vue.js 中自定义一个名为 `CitySelect.vue` 的三级联动下拉选择组件。
我们需要准备省市区的 JSON 数据,这些数据通常包含编码、省市区名称以及级别等信息。在这个例子中,数据已经封装为一个 commonjs 模块 `provinces.js`。每个省市区条目有以下字段:
- `code`: 省市区的编码。
- `sheng`: 省份的简称。
- `name`: 省市区的全名。
- `level`: 级别,1 代表省,2 代表市,3 代表区或县。
- `di`: 县或市的区分(针对市这一级别)。
组件的使用方法如下:
1. 在父组件(如 `App.vue`)中导入 `CitySelect.vue` 组件。
2. 使用 `v-model` 绑定 `cityInfo` 属性,这个属性会被组件设置为选定的省市区信息。
3. 通过计算属性 `cityName` 提取并展示选定的省市区名称。
`App.vue` 示例代码如下:
```html
<template>
<div id="app">
<h5>vue 省市区三联动 demo</h5>
<city-select v-model="cityInfo"></city-select>
<h6>v-model的值是 <code>{{ cityInfo }}</code></h6>
<h6>从v-model得知,你选择了 <i>{{ cityName }}</i></h6>
</div>
</template>
<script>
import CitySelect from './components/CitySelect.vue'
export default {
data() {
return {
cityInfo: '',
}
},
components: {
CitySelect,
},
computed: {
cityName() {
const names = [];
this.cityInfo.province && names.push(this.cityInfo.province.name + ' ');
this.cityInfo.city && names.push(this.cityInfo.city.name + ' ');
this.cityInfo.block && names.push(this.cityInfo.block.name + ' ');
return names.join('');
}
}
}
</script>
<style lang="stylus">
h6 {
padding: 10px;
border: 1px dotted;
}
h6 i {
color: #f00;
border: 1px dotted #ccc;
}
</style>
```
接下来,我们看 `CitySelect.vue` 组件的实现:
```html
<template>
<div class="city-select">
<select v-model="selectedProvince" name="province">
<option v-for="(item, index) in provinces" v-if="item.level === 1" :value="item">{{ item.name }}</option>
</select>
<select v-model="selectedCity" name="city">
<option v-for="(item, index) in cities" :value="item">{{ item.name }}</option>
</select>
<select v-model="selectedBlock" name="block">
<option v-for="(item, index) in blocks" :value="item">{{ item.name }}</option>
</select>
</div>
</template>
<script>
// 三联动选择器
import provinces from './provinces.js'
import Vue from 'vue'
export default {
name: 'CitySelect',
data() {
return {
selectedProvince: null,
selectedCity: null,
selectedBlock: null,
};
},
created() {
// 初始化数据,例如默认选中北京市
this.selectedProvince = provinces.find(province => province.code === '110000');
this.cities = this.selectedProvince.children;
this.selectedCity = this.cities[0];
this.blocks = this.selectedCity.children;
},
watch: {
selectedProvince(newVal) {
this.cities = newVal.children;
this.selectedCity = this.cities[0];
this.blocks = this.selectedCity.children;
},
selectedCity(newVal) {
this.blocks = newVal.children;
this.selectedBlock = this.blocks[0];
},
},
computed: {
cityInfo() {
return {
province: this.selectedProvince,
city: this.selectedCity,
block: this.selectedBlock,
};
},
},
};
</script>
<style scoped>
.city-select select {
margin-right: 10px;
}
</style>
```
在组件内部,我们使用 `v-model` 绑定 `selectedProvince`、`selectedCity` 和 `selectedBlock`,分别对应省、市、区的选择。通过 `watch` 监听这些值的变化,实时更新其他下拉框的选项。同时,我们定义了一个计算属性 `cityInfo`,它会根据当前选定的省市区返回一个对象,供父组件使用。
这个组件实现了省市区的联动效果,当用户在任一选择框中做出改变时,其他选择框会自动更新。通过这种方式,我们可以轻松地在 Vue 项目中实现省市区选择的功能,而且这个组件可以复用在多个地方,提高了代码的可维护性和可重用性。