vue elementui树组件右键
suoh's Blog 人气:0功能描述:
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> 同级增加 </div> <div class="add" @click="addChildNode()"> <i class="el-icon-circle-plus-outline"></i> 子级增加 </div> <div class="delete" @click="deleteNode()"> <i class="el-icon-remove-outline"></i> 删除节点 </div> <div class="edit" @click="editNode()"> <i class="el-icon-edit"></i> 修改节点 </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>
加载全部内容