element tree 优化线条树,添加增删改功能

发布时间 2023-12-08 17:28:13作者: _houjie

需求:树状结构,支持操作功能(同级、子级、修改、删除)。

根据需求是否展示复选框和操作功能。

封装linetree.vue组件:

  1 <template>
  2     <div>
  3         <el-tree :data="list" :props=defaultProps :expand-on-click-node="false" :default-expand-all="true"
  4             ref='treeHight' node-key='id' :show-checkbox=isShowCheck @check="checkNodeData">
  5             <span class="custom-tree-node" slot-scope="{node,data}">
  6                 <span class="el-tree-node__label" @click='handleNodeClick(data)' v-show='!data.isEdit'>
  7                     {{node.label}}
  8                 </span>
  9                 <span v-show='data.isEdit'>
 10                     <el-input v-model='editValue' size='mini' autofocus @blur.stop='nodeBlur(node,data)'
 11                         @keydown.native.enter='nodeBlur(node,data)' :ref="'slotTreeInput'+data.id"></el-input>
 12                 </span>
 13                 <span class="costom-node-tool">
 14                     <span class="el-icon-edit" @click.prevent.stop='editItem(node,data)' title="编辑节点"
 15                         v-show='isShowEdit'></span>
 16                     <span class="el-icon-plus" @click.prevent.stop='addBroItem(node,data)' title="新增同级"
 17                         v-show='isShowEdit'></span>
 18                     <span class="el-icon-circle-plus-outline" @click.prevent.stop='addChildren(node,data)'
 19                         v-show='isShowEdit' title="新增子级"></span>
 20                     <span class="el-icon-delete" @click.prevent.stop='deleteItem(node,data)' title="删除"
 21                         v-show='isShowDel'></span>
 22                 </span>
 23             </span>
 24         </el-tree>
 25     </div>
 26 </template>
 27 <script>
 29     export default {
 30         name: "lineTree",
 31         data() {
 32             return {
 33                 defaultProps: {
 34                     children: 'children',
 35                     label: 'name'
 36                 },
 37                 editValue: '',
 38             };
 39         },
 40         props: {
 41             list: {
 42                 type: Array,
 43                 default: [],
 44             },
 45             isShowEdit: {
 46                 type: Boolean, //是否显示编辑
 47                 default: false
 48             },
 49             isShowDel: {
 50                 type: Boolean, //是否显示删除
 51                 default: false
 52             }, 57             isShowCheck: { //是否显示复选框
 58                 type: Boolean,
 59                 default: false
 60             }
 61         }, 77         methods: {
 78             handleNodeClick(data) {
 79                 this.$emit("treeNodeClick", data)
 80             },
 81             nodeBlur(node, data) {
 82                 if (!data.name) {
 83                     this.$message.warning('名称不可为空');
 84                     return
 85                 } else {
 86                     if (data.isEdit) {
 87                         this.$set(data, 'isEdit', false)
 88                         this.$set(data, 'name', this.editValue)
 89                         var newItem = {
 90                             name: data.name,
 91                             pid: data.pid,
 92                             id: data.id == 'selfId' ? '' : data.id,
 93                         }
 94                         this.$emit('editItem', newItem)
 95                     }
 96                 }
 97             },
 98             // 编辑
 99             editItem(node, item) {
100                 if (!item.isEdit) {
101                     this.$set(item, 'isEdit', true)
102                 }
103                 this.editValue = item.name;
104                 this.$nextTick(() => {
105                     this.$refs['slotTreeInput' + item.id].focus()
106                 })
107             },
108             // 新增同级
109             addBroItem(node, item) {
110                 var newItem = {
111                     id: 'selfId',
112                     pid: item.pid ? item.pid : item.pId,
113                     name: '新增节点',
114                     isEdit: true
115                 }
116                 this.editValue = '新增节点';
117                 this.$refs.treeHight.append(newItem, node.parent)
118                 this.$nextTick(() => {
119                     this.$refs['slotTreeInput' + newItem.id].focus()
120                 })
121             },
122             // 新增子级
123             addChildren(node, item) {
124                 var newItem = {
125                     id: 'selfId',
126                     pid: item.id,
127                     name: '新增节点',
128                     isEdit: true
129                 }
130                 this.editValue = '新增节点';
131                 this.$refs.treeHight.append(newItem, node)
132                 this.$nextTick(() => {
133                     this.$refs['slotTreeInput' + newItem.id].focus()
134                 })
135             },
136             deleteItem(node, item) {
137                 this.$emit('deleteItem', item)
138             },
139             checkNodeData(data, node) {
140                 this.$emit('checkItems', node.checkedKeys)
141             },
142 
143         },
144     };
145 </script>
146 <style scoped>
147
.el-tree {
  background-color: transparent !important;
}
.el-tree-node {
  position: relative;
  margin: 4px 0;
}
.el-tree>.el-tree-node {
  display: inline-block;
  width: 100%;
}
.el-tree::before {
  content: "";
  position: absolute;
  width: 1px;
  height: calc(100% - 36px);
  left: 11px;
  top: 15px;
  border-left: 1px dotted #075d76;
}
.el-tree-node:focus>.el-tree-node__content {
  background-color: transparent;
}
.el-tree-node__content:hover {
  background: transparent!important;
}
.el-tree-node__content:hover .el-tree-node__label {
  background: #112c42!important;
  display: inline-block;
}
.el-tree-node.is-current>.el-tree-node__content {
  background-color: transparent !important;
}
.el-tree-node.is-current>.el-tree-node__content .el-tree-node__label {
  background-color: #194e74 !important;
}
.el-tree-node__content span{
  color: #c8e8ff;
}
.el-tree-node__content {
  position: relative;
  height: 33px;
}
.el-tree-node__content::before {
  content: "";
  position: absolute;
  width: 12px;
  left: 12px;
  top: 15px;
  border-top: 1px dotted #075d76;
}
.custom-tree-node{
  overflow: hidden;
  flex: 1;
  display: flex;
  align-items: center;
  border-bottom: 2px dashed #0e2757;
}
.costom-node-tool{
  width: 102px;
  padding-left: 8px;
}
.costom-node-tool span{
  margin: 0 1px;
}
.el-tree-node__label {
  padding-left: 4px;
  color: #c8e8ff;
  font-size: 18px;
  border-bottom: 2px dashed #0e2757;
  display: inline-block;
  width: 100%;
  height: 30px;
  line-height: 29px;
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.countCon {
  position: absolute;
  bottom: -2%;
  left: 1%;
}
.el-tree .el-tree-node__expand-icon.expanded{
  -webkit-transform: rotate(0deg);
  transform: rotate(0deg);
}
.el-tree .el-icon-caret-right:before{
  background: url(./../../assets/images/fileShow.png) no-repeat;
  content: '';
  display: block;
  width: 18px;
  height: 18px;
  font-size: 16px;
  background-size: 100% 100%;
}
.el-tree .el-tree-node__expand-icon.expanded.el-icon-caret-right:before{
  background: url(./../../assets/images/fileHide.png) no-repeat;
  content: '';
  display: block;
  width: 18px;
  height: 18px;
  font-size: 16px;
  background-size: 100% 100%;
}
.el-tree .el-tree-node__expand-icon.is-leaf::before{
  background: transparent no-repeat;
  content: '';
  display: block;
  width: 18px;
  height: 18px;
  font-size: 16px;
  background-size: 100% 100%;
}
148 </style>