Vue项目中el-cascader级联选择器回显问题及递归解决方案

作者:小布丁时间:2026-10-30 21:20:44浏览:237

本文针对Vue项目中element-ui的el-cascader组件在编辑模式下无法正确回显的问题进行解析。由于后端仅返回末级ID,而组件需要完整的父级ID路径数组,文章提供了一段递归函数代码,通过遍历数据列表查找指定ID并逆向拼接父级节点,从而实现级联选择器的正确回显与数据提交。

在基于Vue和element-ui的前端开发中,级联选择器组件el-cascader的数据回显是一个常见痛点。

1、需求

el-cascader组件内部依赖数组形式的数据结构来维护选中状态,而后端接口通常只要求提交该数组中的最后一个字段(即当前选中项的ID)。然而,在修改数据时,后端往往只返回这最后一个字段,导致前端无法直接构建出完整的层级路径,进而造成el-cascader无法正确回显选中状态。

2、原因分析

实现回显的关键在于v-model属性。只有正确绑定了v-model属性,<el-cascader \/>组件才能渲染出选中效果。此时,v-model绑定的数组中的值(即:targetViewId的值)必须是由当前选中项的ID及其所有父级节点的ID依次组成的完整路径数组,缺一不可。

在基于Vue和element-ui的前端开发中,级联选择器组件el-cascader的数据回显是一个常见痛点。

3、解决方案

鉴于后端返回的数据仅包含最后一级的ID,我们需要在前端编写一个递归函数,根据该ID逆向查找并拼接出其所有父级ID,最终生成后端所需的完整路径数组。以下直接展示核心代码实现。

   /*
    * el-cascader递归获取父级id
    * @param  list 数据列表
    * @param  id 后端返回的id
    * propsCascader 是el-cascader props属性
    **/
    getParentsById(list, id) {
      for (let i in list) {
        if (list[i][this.propsCascader.value || 'value'] == id) {
          return [list[i][this.propsCascader.value || 'value']]
        }
        if (list[i].children) {
          let node = this.getParentsById(list[i].children, id)
          if (node !== undefined) {
            // 追加父节点
            node.unshift(list[i][this.propsCascader.value || 'value'])
            return node
          }
        }
      }
    },

4、效果图

在基于Vue和element-ui的前端开发中,级联选择器组件el-cascader的数据回显是一个常见痛点。

5、注意

如果直接将targetViewId赋值为后端返回的最后一个ID值,虽然界面可能显示有选中状态,但最后一级实际上并未被正确选中。其效果如下:

在基于Vue和element-ui的前端开发中,级联选择器组件el-cascader的数据回显是一个常见痛点。

vue+elementui el-cascader回填功能

<el-cascader
              style="width:97%;margin:5px 0;"
              v-model="dataInfo2"
              :options="subjects"
              :props="defaultProps"
              @change="handleChange"
              placeholder="请选择数据表"
              size="small">
</el-cascader>
updateChart(id) {
      this.$http.get('url?id='+id)
        .then(res => {
          if (res.data.success === true) {
            this.dataTableId = res.data.data.dataTableId
            this.dragTo.values = res.data.data.dragTo
            this.$refs.hottable.editShowTableMe(res.data.data)
            this.$http.post('url', {id: this.dataTableId})
              .then(response => {
                this.dataInfo2 = [response.data.data[0].directoryId,this.dataTableId]
                this.dragFrom.measures = []
                this.dragFrom.measures = response.data.data[0].design.schema.measure
                this.deleteChecked()
              })
              .catch(function(error) {
                console.log(error)
              })
          }
        })
        .catch(err => {
          console.log(err)
        })
    },
    deleteChecked() {
      var arr = []
      for (let i = 0; i < this.dragFrom.measures.length; i++) {
        for (let j = 0; j < this.dragTo.values.length; j++) {
          if (
            this.dragFrom.measures[i].column === this.dragTo.values[j].column
          ) {
            arr.push(i)
          }
        }
      }
      for (var k = 0; k < arr.length; k++) {
        if (k == 0) {
          this.dragFrom.measures.splice(arr[k], 1)   //删除arr[0],删除一个
        } else {
          this.dragFrom.measures.splice(arr[k] - k, 1)   //删除arr[0],删除一个,这样判断的意思是一直从第一个开始删除
        }
      }
},

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。

作者最新文章