element级联地址选择器
一、实现过程总览
- 组件替换:将原有的输入框(
el-input
)替换为级联选择器(el-cascader
),并配置基础属性。 - 数据适配:引入 JSON 地址数据,通过
cascaderProps
映射数据字段(如code
、label
、children
)。 - 值转换逻辑:处理选中值(
code
数组)与显示值(地址字符串)的双向转换。 - 回显功能:编辑时将存储的地址字符串解析为级联选择器的选中状态。
- 表单集成:确保级联选择器与表单验证、提交逻辑无缝结合。
二、核心步骤与逻辑详解
1. 组件替换与基础配置
- 模板修改:
将原el-input
替换为el-cascader
,绑定选中值cascaderValue
和数据源areaList
,并通过props
配置数据映射
<el-form-item label="出差地址" prop="destination"><el-cascaderv-model="cascaderValue":options="areaList":props="cascaderProps"@change="handleCascaderChange"placeholder="请选择省/市/区"></el-cascader>
</el-form-item>
- 数据映射配置:
data() {return {cascaderProps: {value: 'code', // 唯一标识字段(对应JSON中的code)label: 'label', // 显示名称字段(对应JSON中的label)children: 'children' // 子级字段(对应JSON中的children)},areaList: areaList // 引入的JSON地址数据}; }
2. 数据引入与初始化
- 静态数据引入:
- 将 JSON 地址数据保存为独立文件(如
@/utils/area-data.js
),并在组件中引入:import { areaList } from '@/utils/area-data';
- 组件初始化:
在created
钩子中加载数据(若为动态接口需调用 API):created() {this.userId = this.$store.state.user.id;this.getList(); // 原有数据加载// 无需额外加载areaList,已作为静态数据引入 }
3. 选中值与地址字符串的双向转换
-
选中值转字符串(级联选择变化时):
当用户选择地区时,将选中的code
数组转换为label
拼接的字符串(如 “河北 石家庄”):methods: {handleCascaderChange(values) {const selectedLabels = this.getCascaderLabels(values); // 根据code找labelthis.form.destination = selectedLabels.join(' '); // 用空格拼接,可自定义分隔符},// 递归查找code对应的labelgetCascaderLabels(codes) {return codes.map(code => this.findAreaLabel(code, this.areaList));},findAreaLabel(code, areas) {for (const area of areas) {if (area.code === code) return area.label;if (area.children) return this.findAreaLabel(code, area.children);}return '';} }
-
字符串转回选中值(编辑回显时):
从接口获取已有地址字符串(如 “河北 石家庄”),拆分为名称数组后递归查找对应的code
数组:handleUpdate(row) {// 原有逻辑...if (row.destination) {const names = row.destination.split(' '); // 按分隔符拆分成数组this.cascaderValue = this.findCodesByNames(names, this.areaList); // 名称转code} }, findCodesByNames(names, areas, index = 0) {if (index >= names.length) return [];for (const area of areas) {if (area.label === names[index]) {const code = [area.code];if (index < names.length - 1 && area.children) {return code.concat(this.findCodesByNames(names, area.children, index + 1));}return code;}}return []; }
4. 表单验证与提交
- 验证规则:
确保destination
字段在表单验证中必填,并依赖级联选择器的转换逻辑:rules: {destination: [{ required: true, message: "出差目的地不能为空", trigger: "blur" }] }
- 提交逻辑:
在表单提交前,确保destination
已正确赋值(避免级联选择器未触发change
事件):submitForm() {this.$refs.form.validate(valid => {if (valid) {// 手动触发转换(如有必要)if (this.cascaderValue.length > 0 && !this.form.destination) {this.handleCascaderChange(this.cascaderValue);}// 调用接口提交数据(包含destination)}}); }
5. 特殊情况处理
- 直辖市 / 特别行政区:
如北京、上海等地区的children
中存在同名label
(如 “北京”),递归查找时会自动匹配二级数据,无需额外处理。 - 层级深度:
数据结构为三级(省→市→区),级联选择器自动支持,无需配置层级深度。
三、关键逻辑总结
- 数据驱动:通过
cascaderProps
将 JSON 数据字段映射到级联选择器的标准接口,实现数据展示。 - 双向绑定:
cascaderValue
存储选中的code
数组(模型层)。form.destination
存储展示用的地址字符串(视图层),通过handleCascaderChange
实现双向同步。
- 递归解析:利用递归函数实现
code
与label
、字符串与数组的相互转换,适配三级地址结构。 - 无缝集成:级联选择器与若依项目的表单验证、模态框、数据提交等功能完全集成,无需修改原有业务逻辑。