vue+element UI Cascader 级联选择器使用经验分享

6,688 阅读2分钟

最近使用 vue+element UI 框架开发前端项目,用到比较多的是 Cascader 级联选择器。使用过程中有一些心得借此机会跟大家分享一下。 Cascader 级联选择器就是当一个数据集合有清晰的层级结构时,可通过级联选择器逐级查看并选择。在 Element 官网上可以查到它的基础用法,代码如下:

<div class="block">
  <span class="demonstration">hover 触发子菜单</span>
  <el-cascader
    v-model="value"
    :options="options"
    :props="{ expandTrigger: 'hover' }"
    @change="handleChange"></el-cascader>
</div>

它默认的触发方式是 click,如果选择 hover 方式触发,可以对 props 参数设置,将 Trigger 方式改为 hover。 在我的项目中,我想做一个按钮,当鼠标移至按钮时就出现级联选项菜单,当选中选项后就跳转到相关的内容。所以这边结合了 Popover 弹出框和 button 按钮一起使用,参考代码如下:

<div id="button-cascader">
    <el-popover
      ref="popover"
      class="popover"
      placement="bottom-start"
      :trigger="trigger"
      @show="btnAction"
    >
      <el-cascader-panel
        ref="panel"
        v-model="selected"
        :props="{ expandTrigger: 'hover',value: 'id', label: 'name' }"
        :options="options"
        :border="false"
        @change="selectedAction"
      />
      <button ref="button" slot="reference" class="button" :type="buttonType">
        {{ buttonText }}
      </button>
    </el-popover>
  </div>

页面效果图如下:

01.png

但是在测试的时候发现一个问题,就是已选中的选项会被绑定,下次就不能再选,但是我不想这样,我希望每次弹出的菜单都是新的。所以就在每次触发成功时,用 @show 事件去调用 btnAction 方法将绑定值 selected 清空或者使用 this.$refs.panel.clearCheckedNodes() 来清空选中数据。 我这边使用的是将 selected 数据清空,这样的下拉菜单只显示父级,子级不会显示出来。 另外我想实现选中选项后除了可以跳转到相关内容,还希望展示路径,那我这里就用了 Breadcrumb 面包屑,代码如下:

  <el-breadcrumb
     v-if="showTable && !isShowSearch"
     separator-class="el-icon-arrow-right"
     style="margin: 20px"
          >
     <el-breadcrumb-item>
     <span style="font-weight:bold">
     {{pathLabel[0]}}
     </span>
     </el-breadcrumb-item>        
     <el-breadcrumb-item>
     {{ pathLabel[1] }}
     </el-breadcrumb-item>
  </el-breadcrumb>

这里需要获得 Cascader 级联选择器选中的选项路径 label 值。这里我们可以在选项改变时通过 @change 事件来触发 seclectedAction 方法,使用 this.$refs['panel'].getCheckedNodes()[0].pathLabels 来取得节点 label。这样就可以获得相应的路径了。 页面效果图如下:

02.png

项目中还遇到一个问题,我希望 Cascader 级联选择器默认第一个选项。options 的数据格式是树形结构,如下所示:

 [
    {
      "id": 1,
      "pid": 0,
      "name": "电阻",
      "created_at": "2022/02/10",
      "children": [
        {
          "id": 3,
          "pid": 1,
          "name": "贴片电阻",
          "created_at": "2022/02/10"
        },
        {
          "id": 4,
          "pid": 1,
          "name": "插件电阻",
          "created_at": "2022/02/10"
        }
      ]
    },
    {
      "id": 5,
      "pid": 0,
      "name": "电容",
      "created_at": "2022/02/14",
      "children": [
        {
          "id": 7,
          "pid": 5,
          "name": "钽电容",
          "created_at": "2022/02/14"
        },
        {
          "id": 9,
          "pid": 5,
          "name": "贴片型铝电解电容",
          "created_at": "2022/02/14"
        },
        {
          "id": 10,
          "pid": 5,
          "name": "薄膜电容",
          "created_at": "2022/02/15"
        },
        {
          "id": 14,
          "pid": 5,
          "name": "固态电容",
          "created_at": "2022/02/17"
        }
      ]
    },
    {
      "id": 17,
      "pid": 0,
      "name": "连接器",
      "created_at": "2022/02/22",
      "children": [
        {
          "id": 18,
          "pid": 17,
          "name": "排针",
          "created_at": "2022/02/22"
        }
      ]
    }
  ]

我开始是采用简单的取数组值 options[0].children[0].id,如果这个菜单树是不变的,这样好像不会有问题,但是菜单树是变化的,如果 children 不存在就会报错。所以这里采用一个递归函数来无限向下获取子节点。参考代码如下:

searchChildren(arr) {
  var newArr = [];
  for (var item = 0; item < arr.length; item++) {
    newArr.push(arr[item]['id']);
    if (arr[item].children) {
      newArr[item] = this.searchChildren(arr[item].children);
    }
  }
   return newArr;
  }

这样就可以获得每个菜单树的子节点了,通过函数调用来获取想要的子节点。 页面效果如下:

03.png

04.png

关于 Cascader 级联选择器 的分享就写到这里,如果后续还有会再补充进来。希望可以帮助到有类似需求的人。