这里使用element ui得el-select组件,思路是使用监听
<el-select
ref="selectProvinces"
v-model="provinces.value"
placeholder="请选择省"
:disabled="disableds.provinces"
>
<el-option
v-for="province in provinces.children"
:key="province.value"
:label="province.label"
:value="province.value"
>
</el-option>
</el-select>
<el-select
ref="selectCitys"
v-model="citys.value"
placeholder="请选择市"
:disabled="disableds.citys"
:default-first-option="true"
@change="changeCity"
>
<el-option
v-for="city in citys.children"
:key="city.value"
:label="city.label"
:value="city.value"
>
</el-option>
</el-select>
<el-select
ref="selectAreas"
v-model="areas.value"
placeholder="请选择区"
:disabled="disableds.areas"
>
<el-option
v-for="area in areas.children"
:key="area.value"
:label="area.label"
:value="area.value"
>
</el-option>
</el-select>
也可不传
props: {
value: {
type: Array,
required: true
},
dataSource: Array,
},
data() {
return {
provinces: { label: "", value: "", children: [], index: "" },
citys: { label: "", value: "", children: [], index: "" },
areas: { label: "", value: "", children: [], index: "" },
isForcibly: false,
};
},
watch: {
value: {
handler: function() {
//当传入的省市区数组为0时初始化 避免还存留上一个选择过的
if (this.value.length == 0) {
this.provinces = { label: "", value: "", children: [], index: "" };
this.provinces.children = [...this.dataSource].map(item => {
return { label: item.label, value: item.value };
});
this.citys = { label: "", value: "", children: [], index: "" };
this.areas = { label: "", value: "", children: [], index: "" };
}
// 根据value渲染
if (this.value && Array.isArray(this.value) && this.value.length > 0) {
this.isForcibly = true;
let keywords = ["provinces", "citys", "areas"];
for (let index = 0; index < this.value.length; index++) {
let keyword = keywords[index];
this[keyword].value = this.value[index];
if (index === 0) {
this.provinces.index = this.dataSource.findIndex(
item => item.value === this.value[index]
);
this.citys.children = this.dataSource[
this.provinces.index
].children.map(item => {
return { label: item.label, value: item.value };
});
}
if (index === 1) {
this.citys.index = this.dataSource[
this.provinces.index
].children.findIndex(item => item.value === this.value[index]);
if(this.citys.index !== -1) {
this.areas.children = this.dataSource[
this.provinces.index
].children[this.citys.index].children.map(item => {
return { label: item.label, value: item.value };
});
}
}
}
this.$nextTick(() => (this.isForcibly = false));
} else {
this.provinces.value = "";
this.citys.value = "";
this.areas.value = "";
}
},
immediate: true,
deep: true
},
"provinces.value": {
handler: function() {
if (!this.provinces.value) return;
this.provinces.index = this.dataSource.findIndex(
item => item.value === this.provinces.value
);
if (this.isForcibly) return;
this.citys = { label: "", value: "", children: [], index: "" };
this.citys.children = this.dataSource[
this.provinces.index
].children.map(item => {
return { label: item.label, value: item.value };
});
this.areas = { label: "", value: "", children: [], index: "" };
this.$emit("input", [this.provinces.value]);
},
deep: true
},
"citys.value": {
handler: function() {
if (!this.citys.value) return;
this.citys.index = this.dataSource[
this.provinces.index
].children.findIndex(item => item.value === this.citys.value);
if (this.isForcibly) return;
this.areas = { label: "", value: "", children: [], index: "" };
this.areas.children = this.dataSource[this.provinces.index].children[
this.citys.index
].children.map(item => {
return { label: item.label, value: item.value };
});
this.$emit("input", [this.provinces.value, this.citys.value]);
},
deep: true
},
//监听区级选择 如果存在数据那么说明已经选择完毕
"areas.value": {
handler: function() {
if (!this.areas.value || this.isForcibly) return;
this.$emit("input", [
this.provinces.value,
this.citys.value,
this.areas.value
]);
},
immediate: true,
deep: true
},
},
},
created() {
this.provinces.children = [...this.dataSource].map(item => {
return { label: item.label, value: item.value };
});
},
效果如下: