解决element-ui动态加载级联选择器默认选中问题(Cascader)

Posted 前端开发小司机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决element-ui动态加载级联选择器默认选中问题(Cascader)相关的知识,希望对你有一定的参考价值。

前言

最近在开发任务中碰到需要在新增和修改时使用动态加载级联选择器,但是当在修改时设置默认选中项,出现了后端数据返回较慢,导致无法选中和级联框选中了但input框不显示的问题,网上找到的方法也不是很有效,还得使用ref查看组件实例和element-ui cascader源码来寻找解决方法。

完整的实现代码在最后

1. 解决方法

我们知道使用动态加载的级联选择器需要使用lazyLoad函数,那就先开始寻找lazyLoad函数,使用ref查看组件实例,可以看到是在panel下。

再来看看源码,可以发现只需要传入Object数据即可,如:this.$refs.xxx.panel.lazyLoad(val)。

知道了传参和调用,但是传参的参数从哪来?如下图可以看到是从this.$refs.xxx.panel.menus[0]循环比对获取。

如果后端数据返回快的话可以达到要实现的选中效果,如果后端数据返回的较慢就会出现没选中的情况(可以自己在lazyLoad加个一秒延迟测试),这时就需要使用handleExpand(handleExpand也在panel下),并且要在请求结束后执行handleExpand,如何在请求结束时执行handleExpand,我们对代码进行如下修改:

先声明一个waitItemExecution函数并赋给menus[0]循环出的数据,最后在lazyLoad中执行waitItemExecution函数。效果如下图,是不是发现input框没有数据,这还是得去element-ui源码内寻找答案,接着往下看。

当级联选择器选择完毕时,watch下的checkedValue会触发,并执行computePresentContent接着computePresentContent再调用computePresentText。

是不是认为只要对checkedValue进行赋值,input框就有值了?可以试着去查看ref获取的实例下的checkedValue,你会发现已经有值在里面,那为什么没有触发呢?因为!isEqual(val, value)是判断不相等为true,而我们调用的方法不全,导致val和value相等,所以if里面的方法不执行,其实我们只需要调用computePresentText。waitItemExecution函数修改如下:

这样就实现了动态加载级联选择器默认选中的问题。以上的方法只解决了一层和二层的级联情况,超过二层的级联情况不适用,下面将给出最终解决方案代码。

2. 不同层级间的默认选中解决方法

对不同层级的默认选中只需要封装函数并互相调用就可实现(一到N层都可使用),以下是完整代码:

<template><div id="app"><el-cascader v-model="current" :props="props" ref="cascader"></el-cascader></div>
</template>

<script> let id = 0;
let list = [value: '0',, value: '1',, value: '2',, value: '3',,
]
export default name: 'App',data() return current: [],props: lazy: true,lazyLoad(node, resolve) const level = node;function f() list = list.map((item, i) => (label: level ? `$node.value-$i` : item.value,value: level ? `$node.value-$i` : item.value,leaf: item.value === '2' && level === 0 ? true : `$node.value-$i` === '3-2' ? true : level >= 2))resolve(list)if (level > 0) setTimeout(() => f()node.func && node.func(node), 1000)returnf();,mounted() this.current = ['1', '1-3', '1-3-0']// this.current = ['3', '3-2']// this.current = ['2']// this.current = ['0', '0-2', '0-2-3']for (let item of this.$refs.cascader.panel.menus[0]) if (item.value === this.current[0]) this.loadItem(item)return,methods: handleItem(val) if (val && val instanceof Object) this.loadItem(val),loadItem(val) val.func = this.waitItemExecutionthis.$refs.cascader.panel.lazyLoad(val),waitItemExecution(val) for (let item of val.children) if (this.current[val.level] === item.value) this.handleItem(item)breakthis.$refs.cascader.panel.handleExpand(val)this.$refs.cascader.computePresentText(),
 </script> 

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

element-ui el-cascader级联选择器设置指定层级不能选中

有时候用element-ui el-cascader级联选择器添加分类时会遇到最多添加几级的限定.看了文档,只要给需要禁止选择的选项添加disabled属性就可以.但是使用一层一层循环遍历数据感觉很麻烦,自己写了个遍历的方法,纪录下,方便以后使用

贴代码
cascader.vue
<template>
  <el-dialog
    title="添加分类"
    :visible.sync="dialogVisible"
    width="500px">
    <div class="role_contanier">
      <el-form label-width="80px" :model="typeInfo">
        <el-form-item label="分类名称">
          <el-input v-model="typeInfo.name"></el-input>
        </el-form-item>
        <el-form-item label="分类组">
          <el-cascader
            v-model="typeInfo.group"
            :options="typeOptions"
            :props="props"
            @change="handleChange">
          </el-cascader>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm">添加</el-button>
        </el-form-item>
      </el-form>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button @click="dialogVisible = false">取 消</el-button>
      <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
    </span>
  </el-dialog>
</template>
  
  <script>
  export default {
    props: {
      
    },
    data() {
      return {
        dialogVisible: false,
        typeInfo: {
          group: ‘‘,
          name: ‘‘
        },
        typeOptions: [], // 分类层级选项
        props: {
          label: ‘name‘, // 显示的选项
          value: ‘id‘, // 选择的value值
          children: ‘childs‘, // 子级属性名
          checkStrictly: true // 可以选择任意一级
        } // 指定层级属性
      }
    },
    created() {
      this.getTypeOptions()
    },
    mounted() {
     
    },
    methods: {
      // 获取分类级别
      getTypeOptions () {
        // 假设后台返回的数据 4级
        let resDate = [{
          id: 1,
          name: ‘食品‘,
          childs: [
            {id: 3, name: ‘进口食品‘, childs: [
                {id: 5, name: ‘果干‘, childs: [{id: 7, name: ‘坚果‘,}]}, 
                {id: 6, name: ‘面包‘}
              ]
            }, 
            {id: 4, name: ‘国内食品‘}
          ]
          }, {id: 2, name: ‘清洁‘}
        ]
        // 限制只能添加4级分类
        this.setDisable (1, resDate, 3)
        console.log(resDate)
        this.typeOptions = resDate
        this.dialogVisible = true
      },

      // 超过3级,不能选中,子级分类最多4级
      /**
       * count: 当前层级
       * data: 当前层级的数据
       * maxNum: 最多不能超过几级
      */
      setDisable (count, data, maxNum) {
        if (count > maxNum) { //最多几级就写几
          data.forEach(v => {
            v.disabled = true // 超过设定的最大级数,给这一集的数据添加disabled属性
          })
        } else {
          data.forEach(v => {
            if (v.childs && v.childs.length) {
              count++
              this.setDisable(count, v.childs, maxNum)
            }
          })
        }
      },
      // 添加分类
      submitForm () {

      },
      handleChange (val) {
        console.log(val)
      }
    }
  }
  </script>
  
  <style>

  
  </style>

 效果图: 第4级,(坚果不能被选中,也就不能再往下添加分类)

技术图片

以上是关于解决element-ui动态加载级联选择器默认选中问题(Cascader)的主要内容,如果未能解决你的问题,请参考以下文章

element-ui el-cascader级联选择器设置指定层级不能选中

Element-UI级联选择器el-cascader报错Cannot read property level of null

Element-Ui级联选择器递归显示某一级树形结构数据

Element-Ui级联选择器递归显示某一级树形结构数据

vue-element-ui-Cascader 级联选择器支持多选---折腾记

el-cascader级联选择懒加载数据回显解决办法