需求 动态数据遍历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>