|
@@ -0,0 +1,190 @@
|
|
|
+<template>
|
|
|
+ <HcDataTree :h-props="treeProps" :autoExpandKeys="autoExpandKeys" :treeKey="treeKey" :datas="treeLoadNode" @nodeTap="treeNodeClick">
|
|
|
+ <template #default="{node, data, level}">
|
|
|
+ <div :class="level === 1 ? 'level-name':''" class="label flex items-center">
|
|
|
+ <span class="hc-tree-node-type" v-if="level !== 1">县</span>
|
|
|
+ <span>{{node.label }}</span>
|
|
|
+ </div>
|
|
|
+ <!--树组件,操作菜单-->
|
|
|
+ <div v-if="isMenus" :class="node.showTreeMenu?'show':''" class="menu-icon1">
|
|
|
+ <div class="cu-tree-node-popover-menu-icon" @click.prevent.stop="treeLabelContextMenu($event, data, node)">
|
|
|
+ <HcIcon name="apps" ui="text-2xl"/>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </HcDataTree>
|
|
|
+ <!--右键菜单-->
|
|
|
+ <HcContextMenu ref="contextMenuRef" :datas="treeMenu" @closed="handleMenuClosed" @item-click="handleMenuSelect" v-if="isMenus"/>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import {ref,watch,onMounted} from "vue";
|
|
|
+import {isNullES} from "js-fast-way";
|
|
|
+
|
|
|
+//参数
|
|
|
+const props = defineProps({
|
|
|
+ isMenu: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+//渲染完成
|
|
|
+onMounted(()=> {
|
|
|
+
|
|
|
+})
|
|
|
+
|
|
|
+//事件
|
|
|
+
|
|
|
+const treeKey = ref('label')
|
|
|
+const treeRefNode = ref({});
|
|
|
+const treeRefData = ref({});
|
|
|
+const isMenus = ref(props.isMenu);
|
|
|
+const autoExpandKeys = ref([]);
|
|
|
+
|
|
|
+//事件
|
|
|
+const emit = defineEmits(['menuTap', 'nodeTap'])
|
|
|
+
|
|
|
+//数据格式
|
|
|
+const treeProps = {
|
|
|
+ label: 'label',
|
|
|
+ children: 'children'
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//数据
|
|
|
+const treeLoadNode = ref([
|
|
|
+ {
|
|
|
+ label: '征拆区域',
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ label: 'Level two 1-1',
|
|
|
+ children: [
|
|
|
+ {label: 'Level three 1-1-1'}
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'Level two 2-1',
|
|
|
+ children: [
|
|
|
+ {label: 'Level three 2-1-1'}
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'Level two 2-2',
|
|
|
+ children: [
|
|
|
+ {label: 'Level three 2-2-1'}
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'Level two 3-1',
|
|
|
+ children: [
|
|
|
+ {label: 'Level three 3-1-1'}
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: 'Level two 3-2',
|
|
|
+ children: [
|
|
|
+ {label: 'Level three 3-2-1'}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+])
|
|
|
+
|
|
|
+//树被点击
|
|
|
+const treeNodeClick = async ({node, data, keys}) => {
|
|
|
+ treeRefNode.value = node
|
|
|
+ treeRefData.value = data
|
|
|
+ emit('nodeTap', {node, data})
|
|
|
+}
|
|
|
+
|
|
|
+//标题的鼠标右键
|
|
|
+const treeMenu = ref([])
|
|
|
+const contextMenuRef = ref(null)
|
|
|
+const treeLabelContextMenu = (e, data, node) => {
|
|
|
+ if (!isMenus.value) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ e.preventDefault();
|
|
|
+ treeRefNode.value = node;
|
|
|
+ treeRefData.value = data;
|
|
|
+ if (node.level === 1) {
|
|
|
+ treeMenu.value = [{icon: 'add-circle', label: '新增节点', key: "add"}]
|
|
|
+ } else {
|
|
|
+ treeMenu.value = [
|
|
|
+ {icon: 'add-circle', label: '新增节点', key: "add"},
|
|
|
+ {icon: 'draft', label: '编辑节点', key: "edit"},
|
|
|
+ {icon: 'delete-bin', label: '删除节点', key: "del"}
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ node.showTreeMenu = true
|
|
|
+ contextMenuRef.value?.showMenu(e)
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+const handleMenuClosed = () => {
|
|
|
+ const node = treeRefNode.value;
|
|
|
+ if (!isNullES(node)) {
|
|
|
+ treeRefNode.value['showTreeMenu'] = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//鼠标右键菜单被点击
|
|
|
+const handleMenuSelect = async ({key}) => {
|
|
|
+ const node = treeRefNode.value;
|
|
|
+ const data = treeRefData.value;
|
|
|
+ const autoKeys = await getAutoKeys(node)
|
|
|
+ //返回事件
|
|
|
+ emit('menuTap', {key, node, data})
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+//处理自动展开的节点KEY
|
|
|
+const getAutoKeys = async (node) => {
|
|
|
+ let autoKeysArr = []
|
|
|
+ await getNodeExpandKeys(node, autoKeysArr)
|
|
|
+ return autoKeysArr.reverse()
|
|
|
+}
|
|
|
+const getNodeExpandKeys = async ({parent, data}, newKeys) => {
|
|
|
+ const nodeKey = data[treeKey.value] ?? ''
|
|
|
+ if (nodeKey) {
|
|
|
+ newKeys.push(nodeKey)
|
|
|
+ await getNodeExpandKeys(parent, newKeys)
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.data-custom-tree-node {
|
|
|
+ .menu-icon1 {
|
|
|
+ position: relative;
|
|
|
+ vertical-align: bottom;
|
|
|
+ display: inline-block;
|
|
|
+ width: 0;
|
|
|
+ right: -45px;
|
|
|
+ border-radius: 2px;
|
|
|
+ pointer-events: none;
|
|
|
+ background: rgba(255, 255, 255, 0.25);
|
|
|
+ transition: width 0.2s;
|
|
|
+ .cu-tree-node-popover-menu-icon {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ &:hover {
|
|
|
+ .menu-icon1 {
|
|
|
+ right: 0;
|
|
|
+ width: 24px;
|
|
|
+ pointer-events: all;
|
|
|
+ cursor: context-menu;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .menu-icon1.show {
|
|
|
+ right: 0;
|
|
|
+ width: 24px;
|
|
|
+ pointer-events: all;
|
|
|
+ cursor: context-menu;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|