Bootstrap

使用ElementUI树形控件el-tree实现复杂读写操作

需求 动态数据遍历tree
– 只有叶子节点展示复选框
– 非叶子节点通过字段动态展示特别提醒按钮/建议按钮
点击按钮显示特别提醒/建议内容
– 读操作
叶子节点展示历史催记数据
叶子节点 提供可折叠/展示历史催记数据按钮
– 写操作
叶子节点勾选后展示文本框编辑当前催记

实现效果:

写催记效果
在这里插入图片描述
读催记效果
在这里插入图片描述
代码如下:
页面

<template>
  <!-- 
  需求 动态数据遍历tree
  --只有叶子节点展示复选框
  --非叶子节点通过字段动态展示特别提醒按钮/建议按钮
    点击按钮显示特别提醒/建议内容
 --读操作
   叶子节点展示历史催记数据
   叶子节点 提供可折叠/展示历史催记数据按钮
  --写操作
  叶子节点勾选后展示文本框编辑当前催记 
 -->

  <div id="app">
    <div style="text-align: right">
      <el-switch v-model="isWrite" active-text="写催记" inactive-text="读催记">
      </el-switch>
    </div>
    <el-tree
      :data.sync="treeData"
      :show-checkbox="isWrite"
      node-key="id"
      :expand-on-click-node="false"
      default-expand-all
      :props="defaultProps"
      @check="boxCheck"
    >
    <!-- 显示催记历史按钮快捷键 -->
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span @click="() => nodeClick(data, node)">{{ node.label }}</span>
        <span>
          <el-button
            v-popover="'popover-0-' + data.$treeNodeId"
            type="text"
            size="mini"
          >
            <span class="btnRemarkNum">
              {{ getHistorData(data).remarkList.length }}</span
            >
          </el-button>
          <el-popover
            :ref="'popover-0-' + data.$treeNodeId"
            placement="right"
            :title="node.label"
            width="200"
            trigger="click"
          >
            <div class="box">
              <div
                v-for="(item, index) in getHistorData(data).remarkList"
                :key="index"
                class="mark"
                style="margin-bottom: 10px"
              >
                <span style="display: inline-block; padding-bottom: 3px"
                  ><i
                    class="el-icon-time"
                    style="color: #409eff; font-weight: 500; padding: 0 5px"
                  ></i
                  >{{ item.createDatetime }}</span
                >
                <span style="display: inline-block"
                  ><i
                    class="el-icon-wallet"
                    style="color: #409eff; font-weight: 500; padding: 0 5px"
                  ></i
                  >{{ item.remark }}</span
                >
              </div>
            </div>
          </el-popover>
        </span>
        <!-- //特别提醒 -->
        <span class="treeItemBtn" v-if="data.enableSpecialRemind == 'Y'">
          <el-button
            v-popover="'popover-1-' + data.$treeNodeId"
            type="text"
            size="mini"
          >
            <span>特别提醒</span>
          </el-button>
          <el-popover
            :ref="'popover-1-' + data.$treeNodeId"
            placement="right"
            :title="node.label"
            width="200"
            trigger="click"
            :content="data.speechSuggestionContent"
          >
          </el-popover>
        </span>
        <!-- //话术建议 -->
        <span class="treeItemBtn" v-if="data.enableSpeechSuggestion == 'Y'">
          <el-button
            v-popover="'popover-2-' + data.$treeNodeId"
            type="text"
            size="mini"
          >
            <span>话术建议</span>
          </el-button>
          <el-popover
            :ref="'popover-2-' + data.$treeNodeId"
            placement="right"
            :title="node.label"
            width="200"
            trigger="click"
            :content="data.specialRemindContent"
          >
          </el-popover>
        </span>
        <!-- //读 -折叠按钮 -->
        <span
          class="treeItemBtn"
          v-if="!isWrite && getHistorData(data).remarkList.length > 0"
        >
          <el-button type="text" size="mini">
            <i
              v-if="data.enableDefaultUnfold == 'N'"
              class="el-icon-circle-plus-outline"
              @click="data.enableDefaultUnfold = 'Y'"
            ></i>
            <i
              v-else
              class="el-icon-remove-outline"
              @click="data.enableDefaultUnfold = 'N'"
            ></i>
          </el-button>
        </span>
        <!-- 编辑当前催记 -->
        <div
          class="addBox"
          v-if="isWrite && data.isLeafNode == 'Y' && data.isCheck"
        >
          <el-input
            type="textarea"
            placeholder="请输入内容"
            v-model="data.remark"
            maxlength="40"
            show-word-limit
          >
          </el-input>
        </div>
        <!-- 催记历史展示 -->
        <div class="box" v-if="!isWrite && data.enableDefaultUnfold == 'Y'">
          <div
            v-for="(item, index) in getHistorData(data).remarkList"
            :key="index"
            class="mark"
          >
            {{ item.remark }}
          </div>
        </div>
      </span>
    </el-tree>
  </div>
</template>
<script>
export default {
  data() {
    return {
      isShowAdd: 999, //控制是否显示add的输入框
      isWrite: true, //读写催记判断
      nodeList: {}, // 用于保存节点的node信息
      getAllDefaultKeys: [], //默认展开的节点key
      nodeHistoryTreeData: {},
      defaultProps: {
        children: "children",
        label: "mapResultCodeName",
        id: "mapResultCodeId",
        specialRemindContent: "specialRemindContent",
        // disabled: function (data, node) {
        //   if (node.data.isLeafNode === "N") {
        //     return false;
        //   } else {
        //     return true;
        //   }
        // },
      },
      treeData: [
        {
          children: [
            {
              enableDefaultUnfold: "Y", //是否默认折叠
              enableSpecialRemind: "N",//是否显示特别提醒
              enableSpeechSuggestion: "N",//是否显示特别建议
              enableUnfoldButton: "N",//是否显示折叠按钮
              isLeafNode: "N", //是否为叶子节点
              mapResultCode: "00", //节点编码
              mapResultCodeId: "0",//节点编码ID(唯一)
              mapResultCodeName: "地图结代名称0", //节点名称
              specialRemindContent: "特别提醒0",//特别建议内容
              speechSuggestionContent: "话术建议0",//特别提醒内容
              children: [
                {
                  enableDefaultUnfold: "N",
                  enableSpecialRemind: "N",
                  enableSpeechSuggestion: "N",
                  enableUnfoldButton: "N",
                  isLeafNode: "Y",
                  isCheck: "", //是否选择
                  mapResultCode: "00",
                  mapResultCodeId: "0",
                  mapResultCodeName: "地图结代名称0",
                  specialRemindContent: "特别提醒0",
                  speechSuggestionContent: "话术建议0",
                },
                {
                  enableDefaultUnfold: "N",
                  enableSpecialRemind: "N",
                  enableSpeechSuggestion: "N",
                  enableUnfoldButton: "N",
                  isLeafNode: "Y",
                  isCheck: "",
                  mapResultCode: "00",
                  mapResultCodeId: "0",
                  mapResultCodeName: "地图结代名称0",
                  specialRemindContent: "特别提醒0",
                  speechSuggestionContent: "话术建议0",
                },
                {
                  enableDefaultUnfold: "Y",
                  enableSpecialRemind: "N",
                  enableSpeechSuggestion: "N",
                  enableUnfoldButton: "N",
                  isLeafNode: "Y",
                  isCheck: "",
                  mapResultCode: "00",
                  mapResultCodeId: "0",
                  mapResultCodeName: "地图结代名称0",
                  specialRemindContent: "特别提醒0",
                  speechSuggestionContent: "话术建议0",
                },
              ],
            },
            {
              enableDefaultUnfold: "Y",
              enableSpecialRemind: "N",
              enableSpeechSuggestion: "N",
              enableUnfoldButton: "N",
              isLeafNode: "Y",
              isCheck: "",
              mapResultCode: "00",
              mapResultCodeId: "0",
              mapResultCodeName: "地图结代名称0",
              specialRemindContent: "特别提醒0",
              speechSuggestionContent: "话术建议0",
            },
            {
              enableDefaultUnfold: "Y",
              enableSpecialRemind: "N",
              enableSpeechSuggestion: "N",
              enableUnfoldButton: "N",
              isLeafNode: "N",
              mapResultCode: "00",
              mapResultCodeId: "0",
              mapResultCodeName: "地图结代名称0",
              specialRemindContent: "特别提醒0",
              speechSuggestionContent: "话术建议0",
              children: [
                {
                  enableDefaultUnfold: "Y",
                  enableSpecialRemind: "N",
                  enableSpeechSuggestion: "N",
                  enableUnfoldButton: "N",
                  isLeafNode: "Y",
                  isCheck: "",
                  mapResultCode: "00",
                  mapResultCodeId: "0",
                  mapResultCodeName: "地图结代名称0",
                  specialRemindContent: "特别提醒0",
                  speechSuggestionContent: "话术建议0",
                },
                {
                  enableDefaultUnfold: "Y",
                  enableSpecialRemind: "N",
                  enableSpeechSuggestion: "N",
                  enableUnfoldButton: "N",
                  isLeafNode: "Y",
                  isCheck: "",
                  mapResultCode: "00",
                  mapResultCodeId: "0",
                  mapResultCodeName: "地图结代名称0",
                  specialRemindContent: "特别提醒0",
                  speechSuggestionContent: "话术建议0",
                },
                {
                  enableDefaultUnfold: "Y",
                  enableSpecialRemind: "N",
                  enableSpeechSuggestion: "N",
                  enableUnfoldButton: "N",
                  isLeafNode: "Y",
                  isCheck: "",
                  mapResultCode: "00",
                  mapResultCodeId: "0",
                  mapResultCodeName: "地图结代名称0",
                  specialRemindContent: "特别提醒0",
                  speechSuggestionContent: "话术建议0",
                },
              ],
            },
          ],
          enableDefaultUnfold: "Y",
          enableSpecialRemind: "Y",
          enableSpeechSuggestion: "Y",
          enableUnfoldButton: "N",
          isLeafNode: "N",
          mapResultCode: "00",
          mapResultCodeId: "0",
          mapResultCodeName: "地图结代名称0",
          specialRemindContent: "特别提醒0",
          speechSuggestionContent: "话术建议0",
          remark: "",
        },
      ],
      historyTreeData: [
        {
          mapResultCode: "00",
          mapResultCodeId: "0",
          mapResultCodeName: "地图结代名称0",
          remarkList: [
            { createDatetime: 1627973533033, remark: "这是一条催记注释0" },
            { createDatetime: 1627973533033, remark: "这是一条催记注释0" },
            { createDatetime: 1627973533033, remark: "这是一条催记注释0" },
          ],
        },
        {
          mapResultCode: "01",
          mapResultCodeId: "1",
          mapResultCodeName: "地图结代名称1",
          remarkList: [
            { createDatetime: 1627973533033, remark: "这是一条催记注释1" },
            { createDatetime: 1627973533033, remark: "这是一条催记注释1" },
            { createDatetime: 1627973533033, remark: "这是一条催记注释1" },
          ],
        },
        {
          mapResultCode: "02",
          mapResultCodeId: "2",
          mapResultCodeName: "地图结代名称2",
          remarkList: [
            { createDatetime: 1627973533033, remark: "这是一条催记注释2" },
            { createDatetime: 1627973533033, remark: "这是一条催记注释2" },
            { createDatetime: 1627973533033, remark: "这是一条催记注释2" },
          ],
        },
      ],
    };
  },
  created() {
  },
  methods: {
    // 复选框勾选事件
    boxCheck(checkedNodes, checkedKeys) {
      let list = checkedKeys.checkedNodes.filter((item) => {
        if (checkedNodes.$treeNodeId == item.$treeNodeId) return item;
      });
      //复选框选中状态
      if (list && list.length > 0) {
        this.isShowAdd = checkedNodes.$treeNodeId;
        checkedNodes.isCheck = true;
      } else {
        checkedNodes.isCheck = false;
      }
    },
    //获取历史催记数据
    getHistorData(data) {
      let list = this.historyTreeData.filter((item) => {
        if (data.mapResultCodeId == item.mapResultCodeId) {
          return item;
        }
      });
      if (list.length == 1) {
        return list[0];
      }
      return null;
    },
  },
};
</script>
<style lang="less">
//设置只有叶节点显示复选框
.el-tree-node {
  margin-bottom: 10px;
  .is-leaf + .el-checkbox .el-checkbox__inner {
    display: inline-block;
  }
  .el-checkbox__input > .el-checkbox__inner {
    display: none;
  }
}
.el-tree-node__content {
  // height:100% !important;
  height: auto !important; //去掉默认高度
  align-items: flex-start !important; //图标显示上面
  margin-bottom: 10px;
}

.btnRemarkNum {
  display: inline-block;
  padding: 1px 8px;
  background-color: #409eff;
  color: white;
  border-radius: 8px;
}
//节点按钮
.treeItemBtn {
  margin-left: 20px;
  .el-button--text {
    color: #10e29d;
  }
}
</style>


;