vue中使用elementui实现树组件tree右键增删改功能

Ivie ·
更新时间:2024-11-13
· 957 次阅读

功能描述:

1、右击节点可进行增删改

2、可对节点数据进行模糊查询

3、右击第一级节点可以进行同级节点增加

4、双击节点或点击修改节点 都可以对节点获取焦点并进行修改,回车修改成功

5、可对节点进行拖拽,实现节点移动功能 

效果图:

完整代码: <template> <div class="lalala tree-container"> <el-input placeholder="输入关键字进行过滤" v-model="filterText" class="search"> </el-input> <el-tree :data="treeData" node-key="id" default-expand-all @node-click="handleLeftclick" @node-drag-start="handleDragStart" @node-drag-enter="handleDragEnter" @node-drag-leave="handleDragLeave" @node-drag-over="handleDragOver" @node-drag-end="handleDragEnd" @node-drop="handleDrop" @node-contextmenu="rightClick" :filter-node-method="filterNode" draggable :allow-drop="allowDrop" :allow-drag="allowDrag" ref="tree"> <span class="slot-t-node" slot-scope="{ node, data }" @dblclick="editNode(data)"> <span v-show="!data.isEdit"> <span :class="[data.id>= 99 ? 'slot-t-node--label' : '']">{{node.label}}</span> </span> <span v-show="data.isEdit"> <el-input class="slot-t-input" size="mini" autofocus v-model="data.label" :ref="'slotTreeInput'+data.id" @blur.stop="NodeBlur(node,data)" @keydown.native.enter="NodeBlur(node,data)"></el-input> </span> </span> </el-tree> <el-card class="box-card" ref="card" v-show="menuVisible"> <div @click="addSameLevelNode()" v-show="firstLevel"> <i class="el-icon-circle-plus-outline"></i>&nbsp;&nbsp;同级增加 </div> <div class="add" @click="addChildNode()"> <i class="el-icon-circle-plus-outline"></i>&nbsp;&nbsp;子级增加 </div> <div class="delete" @click="deleteNode()"> <i class="el-icon-remove-outline"></i>&nbsp;&nbsp;删除节点 </div> <div class="edit" @click="editNode()"> <i class="el-icon-edit"></i>&nbsp;&nbsp;修改节点 </div> </el-card> </div> </template> <script> export default { name: 'tree', data() { return { eleId: '', isShow: false, currentData: '', currentNode: '', menuVisible: false, firstLevel: false, filterText: '', maxexpandId: 4, treeData: [{ id: 1, label: '一级 1', isEdit: false, children: [{ id: 4, label: '二级 1-1', isEdit: false, children: [{ id: 9, label: '三级 1-1-1', isEdit: false }, { id: 10, label: '三级 1-1-2', isEdit: false }] }] }, { id: 2, label: '一级 2', isEdit: false, children: [{ id: 5, label: '二级 2-1', isEdit: false }, { id: 6, label: '二级 2-2', isEdit: false }] }, { id: 3, label: '一级 3', isEdit: false, children: [{ id: 7, label: '二级 3-1', isEdit: false }, { id: 8, label: '二级 3-2', isEdit: false, children: [{ id: 11, label: '三级 3-2-1', isEdit: false }, { id: 12, label: '三级 3-2-2', isEdit: false }, { id: 13, label: '三级 3-2-3', isEdit: false }] }] }], defaultProps: { children: 'children', label: 'label' } } }, methods: { NodeBlur(Node, data) { console.log(Node, data) if (data.label.length === 0) { this.$message.error('菜单名不可为空!') return false } else { if (data.isEdit) { this.$set(data, 'isEdit', false) console.log(data.isEdit) } this.$nextTick(() => { this.$refs['slotTreeInput' + data.id].$refs.input.focus() }) } }, // 查询 filterNode(value, data) { if (!value) return true return data.label.indexOf(value) !== -1 }, allowDrop(draggingNode, dropNode, type) { if (dropNode.data.label === '二级 3-1') { return type !== 'inner' } else { return true } }, allowDrag(draggingNode) { return draggingNode.data.label.indexOf('三级 3-2-2') === -1 }, // 鼠标右击事件 rightClick(event, object, Node, element) { console.log(event, object) this.currentData = object this.currentNode = Node if (Node.level === 1) { this.firstLevel = true } else { this.firstLevel = false } this.menuVisible = true // let menu = document.querySelector('#card') // /* 菜单定位基于鼠标点击位置 */ // menu.style.left = event.clientX + 'px' // menu.style.top = event.clientY + 'px' document.addEventListener('click', this.foo) this.$refs.card.$el.style.left = event.clientX + 10 + 'px' this.$refs.card.$el.style.top = event.clientY - 60 + 'px' }, // 鼠标左击事件 handleLeftclick(data, node) { this.foo() }, // 取消鼠标监听事件 菜单栏 foo() { this.menuVisible = false // 要及时关掉监听,不关掉的是一个坑,不信你试试,虽然前台显示的时候没有啥毛病,加一个alert你就知道了 document.removeEventListener('click', this.foo) }, // 增加同级节点事件 addSameLevelNode() { let id = Math.ceil(Math.random() * 100) var data = { id: id, label: '新增节点' } this.$refs.tree.append(data, this.currentNode.parent) }, // 增加子级节点事件 addChildNode() { console.log(this.currentData) console.log(this.currentNode) if (this.currentNode.level >= 3) { this.$message.error('最多只支持三级!') return false } let id = Math.ceil(Math.random() * 100) var data = { id: id, label: '新增节点' } this.$refs.tree.append(data, this.currentNode) }, // 删除节点 deleteNode() { this.$refs.tree.remove(this.currentNode) }, // 编辑节点 editNode(data) { console.log(data) this.currentData = data ? data : this.currentData if (!this.currentData.isEdit) { this.$set(this.currentData, 'isEdit', true) } // 获取焦点 this.$nextTick(() => { this.$refs['slotTreeInput' + this.currentData.id].focus() }) }, handleDragStart(node, ev) { console.log('drag start', node) }, handleDragEnter(draggingNode, dropNode, ev) { console.log('tree drag enter: ', dropNode.label) }, handleDragLeave(draggingNode, dropNode, ev) { console.log('tree drag leave: ', dropNode.label) }, handleDragOver(draggingNode, dropNode, ev) { console.log('tree drag over: ', dropNode.label) }, handleDragEnd(draggingNode, dropNode, dropType, ev) { console.log('tree drag end: ', dropNode && dropNode.label, dropType) }, handleDrop(draggingNode, dropNode, dropType, ev) { console.log('tree drop: ', dropNode.label, dropType) }, }, watch: { filterText(val) { this.$refs.tree.filter(val) } }, mounted() { } } </script> <style scoped lang="less"> /* 点击节点时的选中颜色 */ .tree-container /deep/.el-tree-node.is-current > .el-tree-node__content { color: blue !important; } .tree-container /deep/ .el-tree-node__expand-icon.expanded { -webkit-transform: rotate(90deg); transform: rotate(90deg); } .tree-container /deep/ .el-icon-caret-right:before { content: "\e791"; font-size: 18px; } .tree-container /deep/ .el-tree-node__expand-icon { margin-left: 15px; padding: 0px; } .tree-container /deep/ .el-tree-node__expand-icon.is-leaf { margin-left: 0px; } .tree-container /deep/ .el-tree-node { position: relative; padding-left: 16px; // text-indent: 16px; } .tree-container /deep/ .el-tree-node__children { padding-left: 16px; } .tree-container /deep/ .el-tree > .el-tree-node:before { border-left: none; } .tree-container /deep/ .el-tree > .el-tree-node:after { border-top: none; } .tree-container /deep/ .el-tree > .el-tree-node:before { border-left: none; } .tree-container /deep/ .el-tree > .el-tree-node:after { border-top: none; } .tree-container /deep/ .el-tree-node:before { content: ""; left: 10px; position: absolute; right: auto; border-width: 1px; } .tree-container /deep/ .el-tree-node:after { content: ""; left: 10px; position: absolute; right: auto; border-width: 1px; } .tree-container /deep/ .el-tree-node:before { border-left: 1px dashed #ccc; bottom: 0px; height: 100%; top: -19px; width: 1px; } .tree-container /deep/ .el-tree-node:after { border-top: 1px dashed #ccc; height: 25px; top: 20px; width: 20px; } .el-tree-node :last-child:before { height: 40px; } .tree-container { margin: 10px; } .tree-container /deep/ .el-tree .el-tree-node { position: relative; } .tree-container /deep/ .el-tree-node .el-tree-node__content { height: 34px; padding-left: 0px !important; border: none; } .tree-container /deep/ .el-tree-node .el-tree-node__content::before { border-left: 1px dashed #ccc; height: 100%; top: 0; width: 1px; margin-left: 1px; margin-top: 0px; z-index: 8; } .tree-container /deep/ .el-tree-node .el-tree-node__children .el-tree-node__content::before { border-left: 0px dashed #ccc; height: 100%; top: 0; width: 1px; margin-left: 1px; margin-top: 0px; z-index: 8; } .tree-container /deep/ .el-tree-node .el-tree-node__content::after { border-top: 1px dashed #ccc; height: 1px; top: 18px; width: 13px; margin-left: 1px; z-index: 8; } .tree-container /deep/ .el-tree-node .el-tree-node__children .el-tree-node__content::after { border-top: 0px dashed #ccc; } .tree-container .el-tree-node .el-tree-node__content::before, .tree-container .el-tree-node .el-tree-node__content::after { content: ""; position: absolute; right: auto; } /deep/.el-table__placeholder { padding-left: 8px; } /deep/.el-card__body { padding: 10px !important; > div { padding-bottom: 10px; border-bottom: 1px solid #ccc; &:hover { color: blue; } } } /*.lalala {*/ /*position: relative;*/ /*}*/ .text { font-size: 14px; } .el-tree { width: 20%; margin-top: 10px; } .search { width: 20%; } .item { padding: 18px 0; } .add { cursor: pointer; margin-top: 10px; } .delete { margin: 10px 0; cursor: pointer; } .edit { margin-bottom: 10px; cursor: pointer; } .search { cursor: pointer; } .box-card { width: 150px; position: absolute; z-index: 1000; } </style>

到此这篇关于vue中使用elementui实现对树组件tree右键增删改功能的文章就介绍到这了,更多相关vue elementui树组件tree右键增删改内容请搜索软件开发网以前的文章或继续浏览下面的相关文章希望大家以后多多支持软件开发网!



VUE tree

需要 登录 后方可回复, 如果你还没有账号请 注册新账号