vue+elementUi全国地址四级联动--嵌入自定义级别联动

效果图:
默认4级

三级效果
二级效果
一级效果
参数:

参数名类型默认值
value(默认值)Array[]
placeholder(输入框占位文本)String请选择
disabled(是否禁用)Booleanfalse
clearable(是否支持清空选项)Booleantrue
separator(选项分隔符)String/
checkStrictly(是否可以选任意一项)Booleanfalse
level(联动级别)Number4
getAreaData(数据返回)Function{}

数据返回:

字段名称类型
keyArray
valueArray
keyTextString
valueTextString

返回试例:
在这里插入图片描述
HTML代码:

<template>
	<div class="cascader">
		<el-cascader
			v-model="valueData"
			:options="options"
			:props="props"
			:placeholder="placeholder"
			:disabled="disabled"
			:clearable="clearable"
			:separator="separator"
			ref="Cascader"
			class="Cascader"
			@change="handleChange"
			@expand-change="expandChange"
		></el-cascader>
	</div>
</template>

<script>
import { areaData } from "./area-vue";
export default {
	name: "Cascader",
	props: {
		// 默认值
		value: {
			type: Array,
			default: () => []
		},
		// 输入框占位文本
		placeholder: {
			type: String,
			default: "请选择"
		},
		// 是否禁用
		disabled: {
			type: Boolean,
			default: false
		},
		// 是否支持清空选项
		clearable: {
			type: Boolean,
			default: true
		},
		// 选项分隔符
		separator: {
			type: String,
			default: "/"
		},
		// 是否可以选任意一项
		checkStrictly: {
			type: Boolean,
			default: false
		},
		// 联动级别
		level: {
			type: Number,
			default: 4
		},
		// 数据返回
		getAreaData: {
			type: Function,
			default: () => {
				return {
					key: [],
					value: [],
					keyText: "",
					valueText: ""
				};
			}
		}
	},
	data() {
		return {
			valueData: [],
			options: [],
			props: {
				checkStrictly: this.checkStrictly,
				value: "key",
				label: "value"
			}
		};
	},
	mounted() {
		this.initData();
	},
	methods: {
		// 渲染默认数据
		defaultData() {
			if (this.value.length > 0) {
				let data = [];
				this.value.forEach((v) => {
					data.push(v);
					this.expandChange(data);
				});
			}
		},
		// 当选中节点变化时触发
		handleChange() {
			this.$nextTick(() => {
				let node = this.$refs.Cascader.getCheckedNodes()[0];
				let data = {
					key: node ? node.path : [],
					value: node ? node.pathLabels : [],
					keyText: node ? node.path.join(this.separator) : "",
					valueText: node ? node.pathLabels.join(this.separator) : ""
				};
				this.getAreaData(data);
				if (this.$refs.Cascader.dropDownVisible && this.checkStrictly) {
					this.$refs.Cascader.toggleDropDownVisible();
				}
			});
		},
		// 当展开节点发生变化时触发
		expandChange(e) {
			if (this.level >= 2) {
				const dataKey = e[e.length - 1];
				if (areaData[dataKey]) {
					const key = Object.keys(areaData[dataKey]);
					key.forEach((v) => {
						let data = {
							key: v,
							value: areaData[dataKey][v],
							children: []
						};
						if (!areaData[v] || e.length + 1 == this.level) {
							delete data.children;
						}
						this.someFilter(this.options, data, dataKey);
					});
				}
			}
		},
		// 递归当前选中node
		someFilter(array, data, key) {
			array.some((item) => {
				if (item.key == key && item.children) {
					item.children.push(data);
				} else {
					if (item.children) {
						this.someFilter(item.children, data, key);
					}
				}
			});
		},
		// 初始化一级菜单
		initData() {
			if (this.value.length >= this.level) {
				this.value.forEach((v, i) => {
					if (i < this.level) {
						this.valueData.push(v);
					}
				});
			} else {
				this.valueData = this.value;
			}
			const key = Object.keys(areaData["86"]);
			key.forEach((v) => {
				let data = {
					key: v,
					value: areaData["86"][v],
					children: []
				};
				if (this.level == 1) {
					delete data.children;
				}
				this.options.push(data);
			});
			this.defaultData();
		}
	}
};
</script>

<style scoped>
.cascader,
.Cascader {
	width: 100%;
}
</style>

父组件调用:

import Cascader from "@/components/cascader.vue";

components: {
	Cascader
},
<Cascader :value="[]" :getAreaData="getAreaData" />
// 获得选中的地址数据
getAreaData(data) {
	console.log(data);
}

下载原生资源 area-vue.js
适用于本封装组件,占用空间小

export const areaData = {"110000":{"110100":"北京市"},"110100":{"110101":"东城区","110102":"西城区","110105":"朝阳区","110106":"丰台区","110107":"石景山区","110108":"海淀区","110109":"门头沟区","110111":"房山区","110112":"通州区","110113":"顺义区","110114":"昌平区","110115":"大兴区","110116":"怀柔区","110117":"平谷区","110118":"密云区","110119":"延庆区"},...}

下载可直接用的 areaData.js
适用于各类应用场景,导入js就能用,占用空间大

const areaData = [
    {
        "key": "110000",
        "value": "北京市",
        "children": [
            {
                "key": "110100",
                "value": "北京市",
                "children": [
                    {
                        "key": "110101",
                        "value": "东城区",
                        "children": [...]
                     }
             }
         ]
   }
]

个人常用组件—不喜勿喷,谢谢!!!祝君生活愉快~~~~

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你可以使用 Vue 和 Element UI 来实现下拉框的二级联动。下面是一个简单的示例: 首先,在你的 Vue 组件中引入相关的库和组件: ```javascript <template> <div> <el-select v-model="selectedProvince" @change="handleProvinceChange"> <el-option v-for="province in provinces" :key="province" :label="province" :value="province"></el-option> </el-select> <el-select v-model="selectedCity"> <el-option v-for="city in cities" :key="city" :label="city" :value="city"></el-option> </el-select> </div> </template> <script> export default { data() { return { selectedProvince: '', selectedCity: '', provinces: ['省份1', '省份2', '省份3'], // 替换成你的省份数据 cities: { '省份1': ['城市1', '城市2', '城市3'], // 替换成你的城市数据 '省份2': ['城市4', '城市5', '城市6'], '省份3': ['城市7', '城市8', '城市9'] } }; }, methods: { handleProvinceChange() { this.selectedCity = ''; // 清空已选择的城市 } } }; </script> ``` 在上面的示例中,我们使用了两个 `el-select` 组件来展示省份和城市的下拉框。`provinces` 数组存储了所有的省份数据,`cities` 对象存储了每个省份对应的城市数据。当选择省份时,`handleProvinceChange` 方法会被调用,清空已选择的城市并更新城市下拉框的选项。 请注意,上述示例中的省份和城市数据都是静态的,你需要根据实际情况进行替换。你可以从后端或其他数据源中获取数据,并将其动态地传递给组件。 希望这个示例能帮助到你实现下拉框的二级联动!如有任何问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_34096214

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值