一、實現過程總覽
- 組件替換:將原有的輸入框(
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
、字符串與數組的相互轉換,適配三級地址結構。 - 無縫集成:級聯選擇器與若依項目的表單驗證、模態框、數據提交等功能完全集成,無需修改原有業務邏輯。