ant-design-vue tree树添加节点默认选上(有添加编辑删除)
<div> <a-tree :tree-data="treeData" show-icon :expanded-keys="expandedKeys" :selectedKeys="selectedKeys" @select="handleSelected" draggable @drop="onDrop"> <a-icon slot="apartment" type="apartment" style="color:#1890ff" /> <!-- <a-icon slot="file-text" type="file-text" /> --> <i slot="file-text" class="iconfont icon-area" /> <template slot="custom" slot-scope="item"> <span>{{ item.title }}</span> <span class="but_operation"> <span class="but_type iconfont icon-add-k" @click="()=> openModal(item,'1')"></span> <span class="but_type iconfont icon-edit" style="right:120px;" @click="()=> openModal(item,'2')"></span> <span class="but_type iconfont icon-delete" @click="(e)=> remove(item)"></span> </span> <!-- <span class="but_ipt" v-if="visible"> <a-input /> </span> --> </template> </a-tree> <!--添加/编辑--> <a-modal :width="300" :maskClosable="false" :visible="checkVisible" @cancel="cancel" :title="modalTitle" :destroyOnClose="true" :mask="false"> <a-input v-model="textInfo" placeholder="请输入区域" /> <template slot="footer"> <a-button type="primary" @click="append">确定</a-button> <a-button @click="cancel">取消</a-button> </template> </a-modal> </div>
<script> import { Tree, Icon } from 'ant-design-vue' export default { components: { ATree: Tree, // ADirectoryTree: Tree.Directory, // ATreeNode: Tree.Node, AIcon: Icon }, data () { return { treeData: [ { title: '全部', key: '0-0', slots: { icon: 'apartment' }, children: [ { title: '德风石化有限公司', key: '0-0-0', slots: { icon: 'apartment' }, children: [ { title: '公共工程', key: '0-0-0-0', slots: { icon: 'apartment' }, children: [ { title: '中心控制室', key: '0-0-0-0-0', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] }, { title: '辅料管区', key: '0-0-0-0-1', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] }, { title: 'PSA伐区', key: '0-0-0-0-2', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] }, { title: '导热油房区', key: '0-0-0-0-3', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] }, { title: '甲醇裂解区', key: '0-0-0-0-4', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] }, { title: '机柜间', key: '0-0-0-0-5', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] } ] }, { title: '污水处理站', key: '0-0-0-1', scopedSlots: { icon: 'apartment' } } ] } // { title: 'leaf', key: '0-0-1', scopedSlots: { icon: 'apartment' } } ] } ], modalTitle: '', modalIndex: '', checkVisible: false, visible: false, // 是否显示输入框 expandedKeys: [], datas: [], // 暂存的自己及父级的id 层级数组 例如:[爷爷级Id, 父级Id, 自己Id] appendData: '', // 添加的数据 editData: '', // 编辑的数据 textInfo: '', // 输入的区域 isCheck: false, // 是否点击编辑新增删除 selectedKeys: ['0-0-0'] // 默认展开父节点 } }, methods: { handleSelected (keys, info) { // console.log('selected', keys, info) // console.log('点击文字:', info.node.eventKey) if (!this.isCheck) { const itemKey = info.node.eventKey if (this.expandedKeys.length > 0) { if (this.expandedKeys.includes(itemKey)) { this.expandedKeys.splice(this.expandedKeys.indexOf(itemKey), 1) } else { this.expandedKeys = [...this.expandedKeys, itemKey] } } else { this.expandedKeys = [itemKey] } this.selectedKeys = [] this.selectedKeys.push(itemKey) } }, onCheck (checkedKeys, info) { // console.log('onCheck', checkedKeys, info) }, // 递归查找 searchOption (option, arr, type) { this.type = type console.log(option, arr) for (let s = 0; s < arr.length; s++) { console.log(arr[s].key, option.key) if (arr[s].key === option.key) { if (type === 'delect') { arr.splice(s, 1) } else { // 这是编辑数据 this.$set(arr, s, { title: this.textInfo, key: option.key, scopedSlots: { icon: 'file-text', title: 'custom' }, children: option.children }) } break } else if (arr[s].children && arr[s].children.length > 0) { // 递归条件 this.searchOption(option, arr[s].children, this.type) } else { continue } } }, // 新建 openModal (item, index) { console.log(item) this.checkVisible = true // eslint-disable-next-line no-undef index === '1' ? this.modalTitle = '添加区域' : this.modalTitle = '编辑区域' this.appendData = item this.modalIndex = index this.isCheck = true }, // 添加/编辑 append () { if (this.modalIndex === '1') { this.selectedKeys = [] this.defaultExpanded = [] const newChild = { title: this.textInfo, key: '', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] } if (!this.appendData.children) { this.$set(this.appendData, 'children', []) newChild.key = this.appendData.eventKey + '-' + '0' } else { if (this.appendData.children.length > 0) { newChild.key = this.appendData.eventKey + '-' + this.appendData.children.length - 1 } else { newChild.key = this.appendData.eventKey + '-' + '0' } } this.appendData.children.push(newChild) this.selectedKeys.push(newChild.key) this.expandedKeys = [...this.expandedKeys, this.appendData.eventKey] this.checkVisible = false } else { // this.appendData.title = this.textInfo this.searchOption(this.appendData, this.treeData, 'edit') this.checkVisible = false } this.textInfo = '' this.isCheck = false }, // 删除 remove (item) { this.isCheck = true this.$confirm({ title: '您确定删除该条数据吗?', okText: '是', okType: 'danger', cancelText: '否', onOk: async () => { this.searchOption(item, this.treeData, 'delect') this.isCheck = false } }) }, // 递归 获得自己的层级id数组 getItemAndParentsIdArr (arr, key) { for (let i = 0; i < arr.length; i++) { if (arr[i].key === key) { this.datas.push(arr[i]) return true } else { if ( arr[i].children && this.getItemAndParentsIdArr(arr[i].children, key) ) { this.datas.push(arr[i]) return true } } } }, // 获得自己的父级id getFirstParentId (strings, key) { const stringsArr = strings.split('/') const index = stringsArr.indexOf(key.toString()) let parenId if (index !== 0) { parenId = stringsArr[index - 1] } else { parenId = stringsArr[index] } return parenId }, onDrop (info) { console.log('拖动完成:', info) const dropKey = info.node.eventKey // 目标节点的id const dragKey = info.dragNode.eventKey // 拖拽节点的id const dropPos = info.node.pos.split('-') const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]) const loop = (data, key, callback) => { data.forEach((item, index, arr) => { if (item.key === key) { return callback(item, index, arr) } if (item.children) { return loop(item.children, key, callback) } }) } const data = [...this.treeData] // Find dragObject let dragObj // 如果拖动到内部 if (!info.dropToGap) { } else if ( (info.node.children || []).length > 0 && // Has children info.node.expanded && // Is expanded dropPosition === 1 // On the bottom gap ) { } else { // 获得拖拽节点的层级id数组 this.datas this.getItemAndParentsIdArr(data, dragKey) const dragKeyString = this.datas .reverse() .map((v, i) => { return v.key }) .join('/') // 拖拽节点父级id const dragKeyParentId = this.getFirstParentId(dragKeyString, dragKey) /** * --------------------------------分割线--------------------------------------- */ // 获得目标节点的层级id数组 this.datas this.getItemAndParentsIdArr(data, dropKey) const dropKeyString = this.datas .reverse() .map((v, i) => { return v.key }) .join('/') // 目标节点父级id const dropKeyParentId = this.getFirstParentId(dropKeyString, dropKey) /** * --------------------------------分割线--------------------------------------- */ // 只允许在同父级id下进行拖动 if (dragKeyParentId === dropKeyParentId) { loop(data, dragKey, (item, index, arr) => { arr.splice(index, 1) dragObj = item }) let ar let i loop(data, dropKey, (item, index, arr) => { ar = arr i = index }) if (dropPosition === -1) { ar.splice(i, 0, dragObj) } else { ar.splice(i + 1, 0, dragObj) } this.treeData = data } } }, cancel () { this.checkVisible = false this.isCheck = false } } } </script>
全局css修改
/*全局修改a-tree样式——开始*/ .ant-tree { position: relative; } .ant-tree > li span.ant-tree-node-content-wrapper::before, .ant-tree .ant-tree-child-tree > li span.ant-tree-node-content-wrapper::before{ position: absolute; right: 0; left: 0; height: 24px; -webkit-transition: all 0.3s; transition: all 0.3s; content: ''; } .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected::before{ background: rgba(173, 224, 251, 0.4); } .ant-tree li .ant-tree-node-content-wrapper:hover { background-color: transparent; color: #000; } .ant-tree li .ant-tree-node-content-wrapper:hover .but_operation { opacity: 1; } .ant-tree li .ant-tree-node-content-wrapper:hover.ant-tree-node-content-wrapper-normal::before, .ant-tree li .ant-tree-node-content-wrapper:hover.ant-tree-node-content-wrapper::before{ background: rgba(173, 224, 251, 0.4); color: #000; } .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected{ background: transparent; } .ant-tree > li span.ant-tree-node-content-wrapper.ant-tree-node-selected { color: #000; background: transparent; } /*全局修改a-tree样式——结束*/