VueTreeselect 使用史诗级教程

在使用vue2前端页面开发的时候,会用到树形的列表展示数据,使用VueTreeselect可以更加美观的展示数据

VueTreeselect 官方中文地址:Vue-Treeselect | Vue-Treeselect 中文网 (javasoho.com)

默认的基础使用请参考官方的入门文档

很多小伙伴都有使用 RuoYi 框架,其中部门管理中就有使用到本文的主角 VueTreeselect

数据组装

获取数据都是后端返回给我们,但是有些时候后端没有给我们组装好固定的格式,还是需要我们自己手动组装。

其中后端组装数据核心代码

/**
 * Stream分组
 */
@Override
public List<Menu> selectMenuTree() {
    List<Menu> menus = menuMapper.selectList(null);
    //操作所有菜单数据
    Map<Long, List<Menu>> groupMap = menus.stream().collect(Collectors.groupingBy(Menu::getParentId));
    menus.forEach(menu -> {
        menu.setChildren(groupMap.get(menu.getMenuId()));
    });
    List<Menu> collect = menus.stream().filter(menu -> menu.getParentId().equals(0L)).collect(Collectors.toList());
    return collect;
}

很多时候我们前端需求的数据是不需要后端处理好,而是需要自己手动处理。

Javascript核心代码

getDeptList() {
  apiGetDeptList().then((res) => {
    let { data } = res;
    let list = data.map((item) => ({
      id: item.deptId,
      label: item.deptName,
      parentId: item.parentId,
      children: []
    }));
    this.deptOptions = list2tree(list);
  });
}

解构 VueTreeselect 需要的字段,然后调用 list2tree 方法,list 转 tree 和 tree 转 list 代码如下

/**
 * list 转 tree
 * @param list
 * @returns {*[]}
 */
export function list2tree(list) {
  const [map, tree] = [{}, []];
  list.forEach((item) => {
    map[item.id] = item;
  });
  list.forEach((item) => {
    const parent = map[item.parentId];
    if (parent) {
      (parent.children || (parent.children = [])).push(item);
    } else {
      tree.push(item);
    }
  });
  return tree;
}

/**
 * tree 转 list
 * @param tree
 * @returns {*[]}
 */
export function tree2list(tree) {
  const list = [];
  const stack = [...tree];
  console.log(stack);
  while (stack.length) {
    const node = stack.pop();
    const children = node.children;
    if (children) {
      stack.push(...children);
    }
    list.push(node);
  }
  return list;
}

以上数据就处理好了

样式调整

在调整样式的时候,我们点击后出现选项框,但是用鼠标去选择 class 样式的时候,就自动消息了,可以为其添加 :always-open="true" 属性。这里我直接先贴出我最终修改的样式

.el-input--small ::v-deep .vue-treeselect__control {
  height: 32px;
}

.vue-treeselect ::v-deep .vue-treeselect__control {
  padding-left: 10px;
  border-radius: 4px;
  display: flex;
  align-items: center;

  .vue-treeselect__value-container {
    .vue-treeselect__placeholder {
      display: flex;
      align-items: center;
    }

    .vue-treeselect-helper-hide {
      display: none !important;
    }

    .vue-treeselect__single-value {
      color: #606266;
      display: flex;
      align-items: center;
    }

    .vue-treeselect__input-container {
      .vue-treeselect__input {
        display: flex;
        align-items: center;
      }
    }
  }

  .vue-treeselect__x-container {
    margin-left: -20px;
    z-index: 1;
  }
}

.vue-treeselect ::v-deep .vue-treeselect__menu-container {
  label {
    font-weight: normal;
    color: #606266;
  }

  .vue-treeselect__menu {
    margin-top: -3px;
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;

    .vue-treeselect__list {
      padding-left: 5px;

      .vue-treeselect__list-item {
        .vue-treeselect__option--disabled {
          .vue-treeselect__label-container {
            label {
              background-color: #f5f5f5;
              color: rgba(0, 0, 0, 0.25);
            }
          }
        }
      }
    }
  }
}

以上css解决的问题:

  1. 统一了 vue-treeselect 和 input 的 border-radius 样式
  2. 调整了 vue-treeselect 默认展开字体加粗
  3. 统一了 vue-treeselect 和 input 文本内容距离左边的宽度
  4. 为 vue-treeselect 添加 class 样式,class="el-input--small",统一了长度
  5. 添加定位,使文本垂直居中对齐
  6. 修改选项禁用样式统一

最终的样式如下

其他信息记录

  • 选项禁用:添加 isDisabled: true
  • 默认全部展示::defaultExpandLevel="Infinity"
  • 修改无数据的提示信息:noOptionsText="暂无数据"
  • 去掉 children=null 的属性

        

<treeselect
  v-model="form.parDeptId"
  :defaultExpandLevel="Infinity"
  :normalizer="normalizer"
  :options="deptOptions"
  :show-count="false"
  noOptionsText="暂无数据"
  placeholder="请选择上级部门"
/>


normalizer(node) {
  //去掉children=null的属性
  if (node.children == null || (node.children && !node.children.length)) {
    delete node.children;
  }
},

第一次写作………………

  • 26
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_60510238

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值