element-ui使用select组件和tree组件实现下拉树形选择器

template部分


    
        
    

一个三级嵌套就可以搞定

css部分

    .option {
        height: auto;
        line-height: 1;
        padding: 0;
        background-color: #fff;
    }
    .tree {
        padding: 4px 20px;
        font-weight: 400;
    }

网上的办法大多都是直接在option上写,给option加一个高度,然后overflow: auto,这样会有问题, 因为select本身使用的是element-ui自己的滚动条组件, max-height为274px,一旦option设置高度过大,会出现双重滚动条,而且原生滚动条真的有点丑,其实这里只需要给option加一个height: auto,就可以使用select自带的滚动条,不需要单独再加其他滚动。

发现两个问题

  1. 当树展开的时候,动画不流畅,会抖动一下。分析了一下已有的css,发现是因为option本身设置了 line-height: 34px;而树形里没有设置line-height,设置的是高度为26px。这里直接把option的line-height改为1,果然动画流畅了,舒服了。
  2. 当option被选中时,树节点所有的文字都会加粗,随便设置一个font-weight: 400就行。

js部分

要解决几点

  1. 点击树时,下拉框不会自动隐藏,一看文档也没有控制下拉框显示隐藏的属性,然后在select组件源码中找到了visible,控制下拉框显示隐藏
    点击树时设置this.$refs.select.visible = false

  2. 数据回显,通过tree的setCurrentKey方法设置当前高亮的节点,通过getNode方法获取当前id对应的node,拿到对应的label

  3. 不管选没选择内容,打开下拉框的时候,滚动条永远在最底部,实在是太难受了。而一想到是不是不能借助select的滚动,而要给option设置滚动时就更难受了。但是给option设置滚动后,发现滚动条永远在最顶部,舒服了,也有问题。
    突然想到,一个正常不魔改的select组件,选中哪个option时,打开下拉框总能定位到那个选中的,这肯定是select组件内部有个方法做的,偷过来用就行。然后就找到了这个

      scrollToOption(option) {
        const target = Array.isArray(option) && option[0] ? option[0].$el : option.$el;
        if (this.$refs.popper && target) {
          const menu = this.$refs.popper.$el.querySelector('.el-select-dropdown__wrap');
          scrollIntoView(menu, target);
        }
        this.$refs.scrollbar && this.$refs.scrollbar.handleScroll();
      },

scrollToOption?拿来吧你

很明显,要传入一个option对象,而option的$el属性是一个dom,则表现形式就是一个Vue的实例,我这边直接用querySelector获取一个dom, 传入{ $el: dom }也能用。再然后就是找这个dom,发现当树某一节点被点击时,其class会多一个is-current,那么就可以这样写:

let selectDom = document.querySelector('.is-current')
this.$refs.select.scrollToOption({$el: selectDom})

ps: 只针对单选做的,多选还需按照情况改。

组件全部代码







在组件中的使用




效果图

chrome-capture-2022-2-5 (1).gif

代码放在gitgub上了,地址:vue-cy-admin

你可能感兴趣的:(element-ui使用select组件和tree组件实现下拉树形选择器)