element ——tree组件懒加载数据、自定义label、修改高亮样式、回显点击状态

在这里插入图片描述
在这里插入图片描述

需求

  • 整体宽高占一屏,超出滚动条
  • tree组件点击懒加载每一级数据,一共三级
  • 三级节点前加icon,标识是否已学习
  • 点击高亮显示背景图
  • 横向超出省略显示或者横向滚动条
  • 纵向超出纵向滚动条
  • 修改其字体和间距
  • ☆☆☆☆☆从别的页面跳入回显三级点击状态

tree组件

 <el-card
  shadow="hover"
  class="solo mr-10"
  style="height: calc(100vh - 85px); width: 330px"
>
  <div slot="header" class="clearfix">
    <span>问题分类</span>
  </div>
  <div class="scroll-tree">
    <el-scrollbar style="height: 100%">
      <!--accordion  -->
      <el-tree
        ref="popularTree"
        highlight-current
        :props="defaultProps"
        lazy
        :default-expanded-keys="treeExpandedKeys"
        :load="loadNode"
        @node-click="handleNodeClick"
        node-key="knowledgeBaseTypeId"
      >
        <span class="custom-tree-node" slot-scope="{ node, data }">
          <div class="flex_l">
            <i
              v-if="node.level == 3 && data.whetherLearn == 1"
              class="el-icon-success blue size-10 mr-4"
            ></i>
            <span
              style="max-width: 270px"
              class="line-1"
              :class="
                node.level == 1
                  ? 'bold gray-1'
                  : node.level == 2
                  ? 'gray-1'
                  : ''
              "
              >{{ data.knowledgeBaseTypeId }}{{ data.typeName }}</span
            >
          </div>
        </span>
      </el-tree>
    </el-scrollbar>
  </div>
</el-card>

nodeIdArr: [], // 首页跳转过来携带的三级id   [2,3,4]
isFirst: false, // 是否从首页来
treeExpandedKeys: [], // 默认展开的节点id
defaultProps: {
    children: "children",
    label: "typeName",
    isLeaf: "leaf",
},
modelId: null, // 模型id
info: {}, //详情

 mounted() {
    this.nodeIdArr = this.$route.query.id.split(",").map((item) => item * 1);
    if (this.nodeIdArr.length > 0) {
      this.isFirst = true;
    }
  },

  methods: {
    async loadNode(node, resolve) {
      console.log("loadNode", 1111, node);
      // 根据 node.level 获取相应层级的数据
      const level = node.level;
      const { data } = await this.$axios.get(
        "/qualityTrain/knowledgeBase/type/tree?parentId=" +
          (level == 0 ? 0 : node.data.knowledgeBaseTypeId)
      );
      // 从首页跳入的时候,默认选中知识点高亮
      this.highlight(node, data);

      if (node.level == 2) {
        data.forEach((item) => {
          item.leaf = true;
        });
      }
      resolve(data);
    },
    // 从首页跳入的时候,默认选中知识点高亮
    highlight(node, data) {
      if (this.nodeIdArr.length > 0 && this.isFirst) {
        // 默认展开1级和2级
        this.treeExpandedKeys.push(this.nodeIdArr[0]);
        this.treeExpandedKeys.push(this.nodeIdArr[1]);

        if (node.level == 2) {
          console.log("loadNode", 6666, data);
          let currentNode = data.filter(
            (item) => item.knowledgeBaseTypeId == this.nodeIdArr[2]
          );
          if (currentNode.length > 0) {
            // 设置高亮
            this.$nextTick(function () {
              this.$refs.popularTree.setCurrentKey(currentNode[0].knowledgeBaseTypeId);
            });
            // 模拟自动点击
            this.handleNodeClick(currentNode[0]);
          } else {
            this.$message.error("知识点已下架");
          }
          this.isFirst = false;
        }
      }
    },
    handleNodeClick(data) {
      console.log("Clicked node:", data);
      this.info = {};
      this.$refs.modelRef.changeCom([]);

      if (data.modelId != this.modelId) {
        this.modelId = data.modelId;
        if (this.modelId) {
          this.$refs.modelRef.init(this.modelId);
        }
      }
      if (data.level == 3) {
        // 获取知识点详情
        this.$axios
          .get("/qualityTrain/knowledgeBase/type/" + data.knowledgeBaseTypeId)
          .then((res) => {
            this.info = res.data;
            // 获取构件信息
            this.$refs.modelRef.changeCom(
              res.data.componentJsonStr
                ? JSON.parse(res.data.componentJsonStr)
                : []
            );
          });
        // 更新学习状态
        if (data.whetherLearn == 0) {
          this.$axios
            .post("/qualityTrain/knowledgeBase/updateLearnStatus", {
              knowledgeBaseTypeId: data.knowledgeBaseTypeId,
            })
            .then((res) => {
              data.whetherLearn = 1;
            });
        }
      }
    },
},
/deep/.el-card__header {
  font-weight: 700;
  padding: 0.17rem;
  border-bottom: 0px solid #000;
  font-size: 16px;
}
/deep/ .el-tree-node__content {
  height: 33px;
  /* box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.03); */
}
/deep/.el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content {
  /* background: rgba(238, 243, 254, 1);
  border-left: 5px solid rgba(64, 158, 255, 1); */
  background: url("../../assets/img/tree-bg.png") no-repeat center center;
  background-size: 100% 100%;
  color: rgba(64, 158, 255, 1);
  font-weight: 700;
  border-radius: 3px;
  /* padding-left: 31px !important; */
}
/* /deep/.el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content
  .el-tree-node__expand-icon {
  color: rgba(64, 158, 255, 1);
} */
/deep/.el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content
  .el-tree-node__expand-icon.is-leaf {
  color: transparent;
  font-size: 0px;
}
/deep/.el-tree-node__expand-icon {
  color: #333;
}
/deep/.el-tree-node__expand-icon.is-leaf {
  color: transparent;
  font-size: 0px;
}
/* 添加水平滚动条和纵向滚动条 */
.scroll-tree {
  overflow: auto;
  height: calc(100vh - 140px);
}
.scroll-tree ::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
.el-tree {
  display: inline-block;
  min-width: 100%;
}
/deep/.solo .el-card__body {
  padding: 0px;
}
/deep/.solo1 .el-card__body {
  padding-top: 4px;
}

整个组件

<template>
  <div id="index" class="bg w100 vh100">
    <div class="">
      <div class="flex pl-20" style="height: 70px">
        <el-page-header @back="goBack" content="知识库"> </el-page-header>
        <!-- <div class="flex_r">
          已学习<span class="size-26 green bold ml-10">{{
            formattedTime
          }}</span>
        </div> -->
      </div>
      <div class="flex_l flex-top plr-20">
        <el-card
          shadow="hover"
          class="solo mr-10"
          style="height: calc(100vh - 85px); width: 330px"
        >
          <div slot="header" class="clearfix">
            <span>问题分类</span>
          </div>
          <div class="scroll-tree">
            <el-scrollbar style="height: 100%">
              <!--accordion  -->
              <el-tree
                ref="popularTree"
                highlight-current
                :props="defaultProps"
                lazy
                :default-expanded-keys="treeExpandedKeys"
                :load="loadNode"
                @node-click="handleNodeClick"
                node-key="knowledgeBaseTypeId"
              >
                <span class="custom-tree-node" slot-scope="{ node, data }">
                  <div class="flex_l">
                    <i
                      v-if="node.level == 3 && data.whetherLearn == 1"
                      class="el-icon-success blue size-10 mr-4"
                    ></i>
                    <span
                      style="max-width: 270px"
                      class="line-1"
                      :class="
                        node.level == 1
                          ? 'bold gray-1'
                          : node.level == 2
                          ? 'gray-1'
                          : ''
                      "
                      >{{ data.knowledgeBaseTypeId }}{{ data.typeName }}</span
                    >
                  </div>
                </span>
              </el-tree>
            </el-scrollbar>
          </div>
        </el-card>
        <div
          v-show="modelId"
          class="border"
          style="height: calc(100vh - 85px); width: 48%"
        >
          <ZhipeiModel ref="modelRef"></ZhipeiModel>
        </div>
        <div
          class="scroll ml-10"
          :style="`height: calc(100vh - 85px); width: calc(${
            modelId ? '52%' : '100%'
          } - 350px)`"
        >
          <el-card shadow="never">
            <div class="title">知识点</div>
            <div class="text">
              {{ info.typeName }}
            </div>
          </el-card>
          <el-card shadow="never" class="mtb-10">
            <div class="title">详细描述</div>
            <div v-html="info.detailedDescription"></div>
          </el-card>
          <el-card
            shadow="never"
            class="mtb-10"
            v-if="
              info.knowledgeBasePictureList?.length > 0 ||
              info.knowledgeBaseVideoList?.length > 0
            "
          >
            <div v-if="info.knowledgeBasePictureList?.length > 0">
              <div class="title">图片</div>
              <div>
                <el-image
                  v-for="(item, i) in info.knowledgeBasePictureList"
                  :key="i"
                  style="width: 1.14rem; height: 1.14rem; border-radius: 6px"
                  :src="item.pictureUrl"
                  :preview-src-list="
                    info.knowledgeBasePictureList.map((item) => item.pictureUrl)
                  "
                  class="mr-6"
                >
                </el-image>
              </div>
            </div>
            <div v-if="info.knowledgeBaseVideoList?.length > 0">
              <div class="title">视频</div>
              <div class="flex_l flex-wrap">
                <video
                  v-for="(item, i) in info.knowledgeBaseVideoList"
                  :key="i"
                  :style="`width: ${
                    modelId ? '48%' : '3rem'
                  }; height: 2rem; background: #000`"
                  controls
                  :src="item.videoUrl"
                  class="w100 h100 mr-6"
                ></video>
              </div>
            </div>
          </el-card>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { mapState } from "vuex";
export default {
  layout: "layout1",
  data() {
    return {
      nodeIdArr: [], //首页跳转过来携带的三级id
      isFirst: false,
      treeExpandedKeys: [], // 展开的节点id
      defaultProps: {
        children: "children",
        label: "typeName",
        isLeaf: "leaf",
      },
      modelId: null, // 模型id
      info: {}, //题目详情

      itemList: [], //题目列表
      id: null, //选中题目id
    };
  },
  computed: {
    ...mapState(["userInfo"]),
  },
  mounted() {
    this.nodeIdArr = this.$route.query.id.split(",").map((item) => item * 1);
    if (this.nodeIdArr.length > 0) {
      this.isFirst = true;
    }
  },

  methods: {
    async loadNode(node, resolve) {
      console.log("loadNode", 1111, node);
      // 根据 node.level 获取相应层级的数据
      const level = node.level;
      const { data } = await this.$axios.get(
        "/qualityTrain/knowledgeBase/type/tree?parentId=" +
          (level == 0 ? 0 : node.data.knowledgeBaseTypeId)
      );
      // 从首页跳入的时候,默认选中知识点高亮
      this.highlight(node, data);

      if (node.level == 2) {
        data.forEach((item) => {
          item.leaf = true;
        });
      }
      resolve(data);
    },
    // 从首页跳入的时候,默认选中知识点高亮
    highlight(node, data) {
      if (this.nodeIdArr.length > 0 && this.isFirst) {
        // 默认展开1级和2级
        this.treeExpandedKeys.push(this.nodeIdArr[0]);
        this.treeExpandedKeys.push(this.nodeIdArr[1]);

        if (node.level == 2) {
          console.log("loadNode", 6666, data);
          let currentNode = data.filter(
            (item) => item.knowledgeBaseTypeId == this.nodeIdArr[2]
          );
          if (currentNode.length > 0) {
            // 设置高亮
            this.$nextTick(function () {
              this.$refs.popularTree.setCurrentKey(currentNode[0].knowledgeBaseTypeId);
            });
            // 模拟自动点击
            this.handleNodeClick(currentNode[0]);
          } else {
            this.$message.error("知识点已下架");
          }
          this.isFirst = false;
        }
      }
    },
    handleNodeClick(data) {
      console.log("Clicked node:", data);
      this.info = {};
      this.$refs.modelRef.changeCom([]);

      if (data.modelId != this.modelId) {
        this.modelId = data.modelId;
        if (this.modelId) {
          this.$refs.modelRef.init(this.modelId);
        }
      }
      if (data.level == 3) {
        // 获取知识点详情
        this.$axios
          .get("/qualityTrain/knowledgeBase/type/" + data.knowledgeBaseTypeId)
          .then((res) => {
            this.info = res.data;
            // 获取构件信息
            this.$refs.modelRef.changeCom(
              res.data.componentJsonStr
                ? JSON.parse(res.data.componentJsonStr)
                : []
            );
          });
        // 更新学习状态
        if (data.whetherLearn == 0) {
          this.$axios
            .post("/qualityTrain/knowledgeBase/updateLearnStatus", {
              knowledgeBaseTypeId: data.knowledgeBaseTypeId,
            })
            .then((res) => {
              data.whetherLearn = 1;
            });
        }
      }
    },

    goBack() {
      this.$router.go(-1);
    },
  },
};
</script>
<style scoped lang="css">
/deep/.el-card__header {
  font-weight: 700;
  padding: 0.17rem;
  border-bottom: 0px solid #000;
  font-size: 16px;
}
/deep/ .el-tree-node__content {
  height: 33px;
  /* box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.03); */
}
/deep/.el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content {
  /* background: rgba(238, 243, 254, 1);
  border-left: 5px solid rgba(64, 158, 255, 1); */
  background: url("../../assets/img/tree-bg.png") no-repeat center center;
  background-size: 100% 100%;
  color: rgba(64, 158, 255, 1);
  font-weight: 700;
  border-radius: 3px;
  /* padding-left: 31px !important; */
}
/* /deep/.el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content
  .el-tree-node__expand-icon {
  color: rgba(64, 158, 255, 1);
} */
/deep/.el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content
  .el-tree-node__expand-icon.is-leaf {
  color: transparent;
  font-size: 0px;
}
/deep/.el-tree-node__expand-icon {
  color: #333;
}
/deep/.el-tree-node__expand-icon.is-leaf {
  color: transparent;
  font-size: 0px;
}
/* 添加水平滚动条和纵向滚动条 */
.scroll-tree {
  overflow: auto;
  height: calc(100vh - 140px);
}
.scroll-tree ::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
.el-tree {
  display: inline-block;
  min-width: 100%;
}
/deep/.solo .el-card__body {
  padding: 0px;
}
/deep/.solo1 .el-card__body {
  padding-top: 4px;
}
.title {
  font-weight: bold;
  margin: 15px 0;
  /* border-left: 4px solid #00cdba; */
  line-height: 15px;
  padding-left: 6px;
  font-size: 16px;
}
.active {
  background: rgba(0, 205, 186, 0.1);
  color: #00cdba;
  font-weight: 700;
}

.text {
  text-align: justify;
  padding: 0 10px;
}
</style>

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小曲曲

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

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

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

打赏作者

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

抵扣说明:

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

余额充值