关于current-node-key和setCurrentKey默认选中树结构问题

 我这里做的是默认选择树结构的最后一项,需求是高亮默认选中的数据。

整个树结构的代码我先都放上来然后逐一来说

<template>
  <div class="box">
    <div v-loading="isLoading" class="comp-tree">
      <el-button
        class="comp-tr-top"
        type="primary"
        size="small"
        @click="handleAddTop"
        >新增分组</el-button
      >
      <!-- tree -->
      <el-tree
        ref="SlotTree"
        :data="setTree"
        highlight-current
        :props="defaultProps"
        :expand-on-click-node="false"
        :node-key="NODE_KEY"
        @node-click="handleBucketClick"
        :current-node-key="current_node_key"
      >
        <div class="comp-tr-node" slot-scope="{ node, data }">
          <!-- 编辑状态 -->
          <template v-if="node.isEdit">
            <el-input
              v-model="data.name"
              autofocus
              size="mini"
              :ref="'slotTreeInput' + data[NODE_KEY]"
              @blur.stop="handleInput(node, data)"
              @keyup.enter.native="handleInput(node, data)"
            ></el-input>
          </template>
          <!-- 非编辑状态 -->
          <template v-else>
            <!-- 名称: 新增节点增加class(is-new) -->
            <span
              :class="[
                data[NODE_KEY] < NODE_ID_START ? 'is-new' : '',
                'comp-tr-node--name',
              ]"
            >
              {{ node.label }}
            </span>

            <!-- 按钮 -->
            <span class="comp-tr-node--btns">
              <!-- 编辑 -->
              <span
                icon="el-icon-edit"
                size="mini"
                circle
                type="info"
                @click="handleEdit(node, data)"
                v-show="showEdit"
              >
                <i class="iconfont icon-bianji"></i>
              </span>
              <!-- 删除 -->
              <span
                icon="el-icon-delete"
                size="mini"
                circle
                type="danger"
                @click="handleDelete(node, data)"
                v-show="showDel"
              >
                <i class="iconfont icon-shanchu"></i>
              </span>
            </span>
          </template>
        </div>
      </el-tree>
    </div>

    <div>
      <station-info :data="nodeClick" />
    </div>
  </div>
</template>

<script>
import { GroupTree, GroupInfo, DelGroupInfo } from "@/api/taos.js";
import stationInfo from "./stationInfo.vue";
import { mapState } from "vuex";
export default {
  components: { stationInfo },
  name: "station",
  data() {
    return {
      current_node_key: "", //默认选中id
      showEdit: true,
      showDel: true,
      nodeClick: "", //选中节点id
      nodeId: "", //树节点id
      leafId: "", //叶节点id
      isLoading: false, // 是否加载
      setTree: [], // tree数据
      NODE_KEY: "id", // id对应字段
      MAX_LEVEL: 3, // 设定最大层级
      NODE_ID_START: 0, // 新增节点id,逐次递减
      startId: null,
      defaultProps: {
        // 默认设置
        children: "childList",  //这里要和后端给的值对应上
        label: "name",
      },
      //新增一级
      initParam: {
        // 新增参数
        name: "分组",
        pid: 0,
        childList: [
          { name: "遥测" },
          { name: "遥信" },
          { name: "遥控" },
          { name: "遥调" },
        ],
      },
    };
  },
  created() {
    // 初始值
    this.startId = this.NODE_ID_START;
    this.getGroupTree();
  },
  watch: {
    nodeClick(val) {},
    current_node_key: {      //踩坑1:在这里监听current_node_key,之前写在mounted里,我发现是获取不到选中的id的
      handler(value){
        console.log("value",value);
        if(value){
          this.$nextTick(() => {    //踩坑2:this.$nextTick要写,this.$nextTick 将回调延迟到下次DOM更新循环之后执行,在修改数据之后立即使用它,然后等待DOM更新,否则监听不到current_node_key。
        this.$refs.SlotTree.setCurrentKey(this.current_node_key);
      });
        }
      },
      immediate:true,
    },
  },
  mounted() {
    //   this.$nextTick(()=>{
    // 	this.$refs.SlotTree.setCurrentKey(this.current_node_key)
    // })
  },
  methods: {
    //获取当前选中树结构id
    handleBucketClick(val) {
      console.log("树结构", val);
      this.nodeClick = val.id;
      //保存选中type
      this.$store.commit("getType", val.type);
      //保存选中groupId
      this.$store.commit("getGroupId", val.id);
    },
    //树结构
    async getGroupTree() {
      const { data } = await GroupTree();
      console.log("树结构详情", data.data);
      if (data.code === 200) {
        this.setTree = data.data;
        this.setTree.forEach((e) => {
          //最后一个节点作为选中的节点(缓存vuex,展示列表)
          this.current_node_key = e.id;
          e.childList.forEach((i) => {
            if (i.type === "AI" || "AO" || "DI" || "DO") {
              this.showEdit = true;
            } else {
              this.showEdit = true;
            }
          });
        });
        // 缓存默认groupId
        this.$store.commit("getCurrent_node_key", this.current_node_key);
      }
    },
    handleDelete(_node, _data) {
      // 删除节点
      // 删除操作
      let DeletOprate = () => {
        this.$nextTick(() => {
          if (this.$refs.SlotTree) {
            this.nodeId = this.$store.state.taosStore.groupId;
            console.log("删除id", this.nodeId);
            const { data } = DelGroupInfo(this.nodeId);
            this.$message.success("删除成功!");
            //TODO删除
            // if (data.code === 200) {
            //   this.$message({
            //     message: "删除成功",
            //     type: "success",
            //   });
            // }
            this.$refs.SlotTree.remove(_data);
          }
        });
      };
      // 二次确认
      let ConfirmFun = () => {
        this.$confirm("是否删除此节点?", "提示", {
          confirmButtonText: "确认",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(() => {
            DeletOprate();
          })
          .catch(() => {});
      };
      // 判断是否新增: 新增节点直接删除,已存在的节点要二次确认
      _data[this.NODE_KEY] < this.NODE_ID_START ? DeletOprate() : ConfirmFun();
      this.getGroupTree();
    },
    async handleInput(_node, _data) {
      // 修改节点
      // 退出编辑状态
      if (_node.isEdit) {
        this.$set(_node, "isEdit", false);
        const { data } = GroupInfo(_data);
      }
    },
    // 点击编辑图标
    handleEdit(_node, _data) {
      // 编辑节点
      // 设置编辑状态
      if (!_node.isEdit) {
        this.$set(_node, "isEdit", true);
      }
      // 输入框聚焦
      this.$nextTick(() => {
        if (this.$refs["slotTreeInput" + _data[this.NODE_KEY]]) {
          this.$refs[
            "slotTreeInput" + _data[this.NODE_KEY]
          ].$refs.input.focus();
        }
      });
    },
    async handleAddTop() {
      // 添加顶部节点
      let obj = JSON.parse(JSON.stringify(this.initParam)); // copy参数
      // obj[this.NODE_KEY] = --this.startId; // 节点id:逐次递减id
      this.setTree.unshift(obj);
      const { data } = GroupInfo(obj);
    },
  },
};
</script>

<style lang="less" scoped>
// 树结构默认选中样式
/deep/.el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content {
  color: #4d95fd;
}
.box {
  display: flex;
  flex-direction: row;
  // width: 100%;
}
// /* common end */
.comp-tree {
  padding: 20px;
  height: calc(100% - 40px);
  background-color: #fff;
  border-radius: 8px;
  width: 200px !important;
  // max-width: 700px;
  height: 85.8vh;
  // overflow: auto;
  // 顶部按钮
  .comp-tr-top {
    width: 100px;
    margin-bottom: 2em;
    font-size: 16px;
  }
  // 自定义节点
  .el-tree {
    width: 200px;
  }
  /deep/.comp-tr-node {
    padding: 10px 0 15px 0;
    display: block !important;
    width: 100% !important;
    position: relative !important;
    // 固有label
    .comp-tr-node--name {
      display: inline-block;
      font-size: 16px;
      line-height: 40px;
      min-height: 40px;
      // 新增label
      &.is-new {
        font-weight: 500;
        font-size: 16px;
      }
    }
  }
  /deep/.comp-tr-node--btns {
    margin-left: 10px;
    // opacity: 0;
    position: absolute !important;
    right: 0 !important;
    top: 20px !important;
  }
  // 高亮显示按钮
  .is-current {
    & > .el-tree-node__content {
      .comp-tr-node--btns {
        opacity: 1;
      }
    }
  }
  // 悬浮显示按钮
  .el-tree-node__content {
    &:hover {
      .comp-tr-node--btns {
        opacity: 1;
      }
    }
  }
}
</style>

        总的来说设置默认选中状态就是要current_node_key和setCurrentKey配合使用,然后还要注意的是要加this.$nextTick,不然获取不到id,代码中我也注释说明了,还有就是很多博客说highlight-current的位置要稍微置后写,不然高亮给不到,但是我实验了不管前后顺序都是ok的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值