Bootstrap

el-tree没有复选框时,选中、currentNodeKey高亮、定位、刷新后保留展开状态功能的实现

机缘

在使用无选择框的el-tree时遇到的一个问题,当点击某行数据的时候会有背景色,但是当鼠标点击别处时,便失去焦点,背景色随之消失了。

这篇文章主要介绍了vue2+elementUI的el-tree的选中、高亮、定位功能,其中定位功能涉及到无论当前在那个菜单,删除某一项菜单后,刷新菜单会跳到全部需要保留历史展开状态,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
想实现的效果如下:

 鼠标滑过高亮文字和背景色,鼠标点击别的地方,背景色和文字都保持位置不变


实现方法

html部分实现

<el-tree
                ref="tree"
                :data="treeData"
                :current-node-key="currentNodeKey"
                node-key="id"
                :default-expanded-keys="defaultExpandedKeys"
                @node-click="handleNodeClick"
                @node-expand="handleNodeExpand"
                @node-collapse="handleNodeCollapse"
                :highlight-current="true"
                :expand-on-click-node="false"
                :props="defaultProps"
                v-loading="treeLoading"
        >

js部分实现

 export default {
    data() {
      return {
        defaultProps: {
          children: "children",
          label: "name",
        },
        currentNodeKey: 1, // 当前选中节点
        treeLoading: false, // treeLoading
        defaultExpandedKeys: ['1'],
        treeData: [{
          id: 1,
          name: '全部',
          level: 1,
          children: [{
            id: 2,
            level: 2,
            name: '未分类',
          },
            {
              id: 4,
              name: '二级 1-1',
              level: 2,
              children: [{
                id: 9,
                level: 3,
                name: '三级 1-1-1'
              }, {
                id: 10,
                level: 3,
                name: '三级 1-1-2'
              }]
            }]
        }]
      };
    },
    methods: {
     /**
       * @description:  点击节点
       * @param {Object} data
       * @param {Object} node
       * @return {*}
       */
      handleNodeClick(data, node){
        this.currentNodeKey = data.id;
        // 判断点击的层级进行操作
        if(node.level === 1){
          console.log('第一层data1',data);
          console.log('第一层node1',node);
        }else if(node.level === 2){
          console.log('第二层data2',data);
          console.log('第二层node2',node);
        }else if(node.level === 3){
          console.log('第三层data3',data);
          console.log('第三层node3',node);
        }
      },
      /**
       * @description:  树节点展开
       * @param {Object} data
       * @return {*}
       */
      handleNodeExpand (data) {
        // 判断当前节点是否存在, 存在不做处理,不存在则存到数组里
        if (!this.defaultExpandedKeys.includes(data.id)) {
          this.defaultExpandedKeys.push(data.id)
        }
      },
      /**
       * @description:  树节点关闭
       * @param {Object} data
       * @return {*}
       */
      handleNodeCollapse (data) {
        for (let i = 0; i < this.defaultExpandedKeys.length; i++) {
          if (this.defaultExpandedKeys[i] === data.id) {
            this.defaultExpandedKeys.splice(i, 1);
          }
        }
      },
/**
       * @description: 获取树形结构菜单
       * @param {*}
       * @return {*}
       */
      async getTreeData(){
        this.treeLoading = true;
        await request({
          url: ``,
          method: 'get',
        }).then(res => {
          this.treeData = res.data;
          // 不加会跳到全部
          this.$nextTick(() => {
            this.$refs['tree'].setCurrentKey(this.currentNodeKey);
          })
        }).finally(() => {
          this.treeLoading = false;
        });
      },
/**
       * @description: 文件夹删除
       * @param {String} id
       */
      delFileConfirm(id) {
        const h = this.$createElement;
        this.$msgbox({
          title: '提示',
          message: h('p', null, [h('span', null, `确认删除该文件夹及其子文件夹吗?`)]),
          showCancelButton: true,
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          beforeClose: (action, instance, done) => {
            if (action === 'confirm') {
              instance.confirmButtonLoading = true;
              request({
                url: '',
                method: 'post',
                data: {
                  id,
                },
              }).then(async (res) => {
                if (res.code === '0') {
                  this.$message({
                    type: 'success',
                    message: '删除成功!'
                  });
                  done();
                  await this.getTreeData();
                }
              }).finally(()=> {
                instance.confirmButtonLoading = false;
              })
            } else {
              done();
              instance.confirmButtonLoading = false;
            }
          }
        }).then(action => {});

      },
    }
  };
</script>

css部分实现 

主要是为了实现高亮

<style scoped>
/*  鼠标hover改变背景颜色 */
  .el-tree /deep/ .el-tree-node  .el-tree-node__content:hover {
    background-color: #f0f7ff !important;
    color: #409eff;
  }
  /*  颜色高亮 */
  /deep/ .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
    color: #409eff;
  }
</style>

参数示意

:default-expand-all ----> 默认打开全部节点

:default-expanded-keys----> 默认打开的节点

:data="treeData" ----> 必写 展示数据

@node-click="handleNodeClick" ----> 节点被点击时的回调

node-key="id" ----> 设置选中的数据的key

 :current-node-key="currentNodeKey" ----> 设置初始选中的值

:highlight-current="true" ----> 设置高亮 必须写

:props="defaultProps" ----> 可以配置节点标签的属性值

关键点

  1. 设置highlight-current为true
  2. 设置current-node-key为currentNodeKey,同时刷新接口时重新设置currentNodeKey,代码如下
    this.$nextTick(() => {
      this.$refs['tree'].setCurrentKey(this.currentNodeKey);
    })
  3. 若不是默认展开全部,需要刷新后保持原展开的数据继续展开状态
    @node-expand="handleNodeExpand" // 展开节点时触发的函数
    @node-collapse="handleNodeCollapse" // 关闭节点时触发的函数


;