找回密码
 立即注册
首页 业界区 业界 在Vue3+ElementPlus前端中,使用watch监控对象变化,实 ...

在Vue3+ElementPlus前端中,使用watch监控对象变化,实现字典列表的级联更新处理

訾懵 2025-8-21 10:20:53
在Vue3+ElementPlus前端中,有时候一些字典的关联显示,需要使用级联,因此一般使用watch监控对象变化,实现字典列表的级联更新。本篇随笔介绍基于实际案例来实现多级关联的处理操作,以供参考。
1、省市区的级联案例

在很多实际业务项目中,往往都可能涉及到级联显示的场景。比如有 省份 -> 城市 -> 区县 的字典数据,用户在选择“省份”时,自动更新“城市”选项;选择“城市”时,自动更新“区县”选项。基本的处理过程如下所示。

  • 使用 ref/reactive 保存选择值和字典数据。
  • 使用 watch 监听上级字段变化,动态更新下级字典数据。
  • 下级值要 清空/重置,避免残留无效值。
对于省市区简单例子的Vue3模板界面,如下代码所示。
  1. <template>
  2.   
  3.     <label>省份:</label>
  4.     <select v-model="province">
  5.       <option :value="null">请选择</option>
  6.       <option v-for="p in provinces" :key="p.code" :value="p.code">{{ p.name }}</option>
  7.     </select>
  8.     <label>城市:</label>
  9.     <select v-model="city">
  10.       <option :value="null">请选择</option>
  11.       <option v-for="c in cities" :key="c.code" :value="c.code">{{ c.name }}</option>
  12.     </select>
  13.     <label>区县:</label>
  14.     <select v-model="area">
  15.       <option :value="null">请选择</option>
  16.       <option v-for="a in areas" :key="a.code" :value="a.code">{{ a.name }}</option>
  17.     </select>
  18.   
  19. </template>
复制代码
在其script脚本代码的操作中,使用watch来处理界面代码逻辑如下所示。
  1. [/code]有时候,对于字段的处理顺序,我们可能需要引入nextick来处理。
  2. nextTick 在 Vue3 里非常适合用来 [b]等 DOM 和响应式更新完成再执行逻辑[/b]。
  3. 在「编辑场景级联字典」这种情况里,nextTick 可以解决 [b]字典更新和已有值赋值的时序问题[/b]。
  4. [code]// 监听省份变化 → 更新城市字典
  5. watch(
  6.   () => form.province,
  7.   async (newVal) => {
  8.     if (!newVal) {
  9.       cities.value = []
  10.       form.city = null
  11.       form.area = null
  12.       return
  13.     }
  14.     cities.value = await fetchCities(newVal)
  15.     // ⚡ 用 nextTick 等 cities 更新后再校验
  16.     await nextTick()
  17.     if (!cities.value.find(c => c.code === form.city)) {
  18.       form.city = null
  19.       form.area = null
  20.     }
  21.   },
  22.   { immediate: true }
  23. )
复制代码
 
2、电力记录业务的处理案例

在我们的一个项目案例中,对于电力的一些级联处理,也有类似的参考价值,如对于电力记录的处理中,我们需要根据地区进行一级、二级、三级能耗的下拉列表级联更新,方便在录入的时候进行关联显示。下面是数据列表的显示部分界面截图。
1.png

 在数据编辑或者新增的情况下,我们需要根据这些内容进行级联的显示处理,那么界面如下所示。
 
2.png

我们看到,以上几个了下拉列表的字典内容,都存在一定的级联关系,如选择区域后,需要更新一级列表、选择一级列表后,需要更新二级列表、选择二级列表后,需要更新三级列表等等。
我们使用watch来跟踪对象的变化,并及时进行字典数据的更新,如下逻辑代码所示。
  1. const area = ref([]); // 能源区域
  2. const level1 = ref([]); // 一级能耗计量
  3. const level2 = ref([]); // 二级能耗计量
  4. const level3 = ref([]); // 三级能耗计量
  5. const <strong>initArea</strong> = () => {
  6.   electrecord.GetFieldDict('area').then(data => {
  7.     // console.log(data);
  8.     area.value = data;
  9.   });
  10. };
  11. // 判断下拉框的值是否有改变
  12. watch(
  13.   () => editForm.area,
  14.   (newValue) => {
  15.     if (!newValue) {
  16.       editForm.level1 = '';
  17.       editForm.level2 = '';
  18.       editForm.level3 = '';
  19.     }
  20.     if (newValue) {
  21.       const whereStr = `area='${newValue}'`;
  22.       electmerter.GetFieldDict('level1', whereStr).then(data => {
  23.         // console.log(data);
  24.         level1.value = data;
  25.       });
  26.     }
  27.   },
  28.   { immediate: true }
  29. );
  30. watch(
  31.   () => editForm.level1,
  32.   (newValue) => {
  33.     if (!newValue) {
  34.       editForm.level2 = '';
  35.       editForm.level3 = '';
  36.       editForm.devicename = '';
  37.       editForm.devicecode = '';
  38.       editForm.lastnumber = 0;
  39.     }
  40.     if (newValue) {
  41.       const whereStr = `level1='${newValue}' and area='${editForm.area}'`;
  42.       <strong>electmerter.GetFieldDict</strong>('level2', whereStr).then(data => {
  43.         // console.log(data);
  44.         level2.value = data;
  45.       });
  46.     }
  47.   },
  48.   { immediate: true }
  49. );
  50. watch(
  51.   () => editForm.level2,
  52.   (newValue) => {
  53.     if (!newValue) {
  54.       editForm.level3 = '';
  55.       editForm.devicename = '';
  56.       editForm.devicecode = '';
  57.       editForm.lastnumber = 0;
  58.     }
  59.     if (newValue) {
  60.       const whereStr = `level2='${newValue}' and area='${editForm.area}' and level1='${editForm.level1}'`;
  61.       electmerter.GetFieldDict('level3', whereStr).then(data => {
  62.         // console.log(data);
  63.         level3.value = data;
  64.       });
  65.     }
  66.   },
  67.   { immediate: true }
  68. );
  69. watch(
  70.   () => editForm.level3,
  71.   (newValue) => {
  72.     if (!newValue) {
  73.       editForm.devicename = '';
  74.       editForm.devicecode = '';
  75.       editForm.lastnumber = 0;
  76.     }
  77.   },
  78.   { immediate: true }
  79. );
复制代码
其中 electmerter.GetFieldDict 是ES6类中的API调用函数,主要对标后端代码里面,通用处理的获取对应表的关联字段列表。
后端通用的处理代码如下C#代码所示。
  1.         /// <summary>
  2.         /// 根据字段名称,获取对应的字典列表
  3.         /// </summary>
  4.         /// <param name="fieldName">字段名称</param>
  5.         /// <param name="whereStr">条件字符串,如Age > 20 AND IsActive = true</param>
  6.         /// <returns></returns>
  7.         public virtual async Task<List<CListItem>> GetFieldDict(string fieldName, string whereStr)
  8.         {
  9.             var list = new List<CListItem>();
  10.             if (!fieldName.IsNullOrEmpty())
  11.             {
  12.                 //var sql = $"Select distinct {fieldName} from Table";
  13.                 var query = this.EntityDb.AsQueryable();
  14.                 if (!string.IsNullOrWhiteSpace(whereStr))
  15.                 {
  16.                     query = query.Where(whereStr);
  17.                 }
  18.                 var fieldList = await query.Distinct().Select<string>(fieldName).ToListAsync();
  19.                 if(fieldList != null && fieldList.Count >0)
  20.                 {
  21.                     var sortedList = fieldList
  22.                         .OrderBy(name => GetSortIndex(name))  // 主排序:数字前缀
  23.                         .ThenBy(name => name)                // 次排序:中文拼音顺序
  24.                         .ToList();
  25.                     list = sortedList.Select(s => new CListItem(s)).ToList();
  26.                 }
  27.             }
  28.             return list;
  29.         }
复制代码
以上就是一些简单案例上对于watch的使用,用于处理多级关联更新的情况下的功能实现。

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册