之前做项目的时候有个需求是在form表单里插入三级地址级联选择,去网上找了一些插件,但没有一个符合自己的需求,就尝试自己去写了下组件,效果还可以,具体如下:
首先,是页面布局
<div id="comPCA">
<!-- 省 -->
<el-select
placeholder="省"
@focus="insertProvinceData()"
v-model="formAddressData.province"
@change="chooseProvince"
>
<template v-for="(item, index) in provinceData">
<el-option
:key="index"
:label="item.label"
:value="item.cityname"
></el-option>
</template>
</el-select>
<!-- 市 -->
<el-select
placeholder="市"
v-model="formAddressData.city"
@change="chooseCity"
>
<template v-for="(item, index) in cityData">
<el-option
:key="index"
:label="item.label"
:value="item.cityname"
></el-option>
</template>
</el-select>
<!-- 区 -->
<el-select placeholder="区" v-model="formAddressData.area">
<template v-for="(item, index) in areaData">
<el-option
:key="index"
:label="item.label"
:value="item.cityname"
></el-option>
</template>
</el-select>
</div>
然后是js部分,先看props
props: ["allAddress", "modAddress"],
这里的allAddress
用来接收从后台拿过来的地址数据,用来填充地址选项,modAddress
用来接收从父组件传过来的已创建的地址,用在修改功能
接下来是data
// 省市区的数据选择
provinceData: [],
cityData: [{ label: "", cityname: "" }],
areaData: [{ label: "", cityname: "" }],
// 该对象用来格式化以后抛给父组件
formAddressData: {
province: "",
city: "",
area: "",
},
然后是剩下的代码
methods: {
// 插入省份数据
insertProvinceData() {
this.provinceData = this.allAddress;
},
// 省份选择
chooseProvince(value) {
this.cityData = this.allAddress.filter((item) => {
return value == item.cityname;
})[0].children;
this.formAddressData.city = "";
this.formAddressData.area = "";
},
// 城市选择
chooseCity(value) {
this.areaData = this.cityData.filter((item) => {
return value == item.cityname;
})[0].children;
this.formAddressData.area = "";
},
},
mounted() {
// 将已有的地址填充到地址选择器里,变量modAddress的格式是"XXX XXX XXX"
if (this.modAddress != "") {
let tmp;
tmp = this.modAddress.split(" ");
this.insertProvinceData();
this.chooseProvince(tmp[0]);
this.chooseCity(tmp[1]);
[
this.formAddressData.province,
this.formAddressData.city,
this.formAddressData.area,
] = [tmp[0], tmp[1], tmp[2]];
}
},
watch: {
// 深度监听,当省、市、区三个值都被选择的时候将其格式化成"XXX XXX XXX"这样的字符串形式
formAddressData: {
handler() {
if (!this.formAddressData.area) {
this.$emit("formAddressData", "");
} else {
let tmp = "";
let count = 0;
for (let key in this.formAddressData) {
if (count != 2) {
tmp = tmp + this.formAddressData[key] + " ";
} else {
tmp += this.formAddressData[key];
}
count++;
}
this.$emit("formAddressData", tmp);
}
},
deep: true,
},
},