|
@@ -1,209 +1,46 @@
|
|
|
<template>
|
|
|
- <ElTree class="hc-tree-node tree-line" ref="ElTreeRef" :props="ElTreeProps" :data="datas" highlight-current accordion node-key="primaryKeyId"
|
|
|
- :default-expanded-keys="TreeExpandKey" @node-click="ElTreeClick" @node-contextmenu="ElTreeLabelContextMenu" :indent="0">
|
|
|
- <template #default="{ node, data }">
|
|
|
- <div class="data-custom-tree-node" :id="`${idPrefix}${data['primaryKeyId']}`">
|
|
|
- <!--树组件,节点名称-->
|
|
|
- <div class="label" :class="node.level === 1?'level-name':''">
|
|
|
- <span :class="data?.colorStatus === 2?'text-blue':data?.colorStatus === 3?'text-orange':data?.colorStatus === 4?'text-green':''" v-if="isColor">{{ node.label }}</span>
|
|
|
- <span v-else>{{ node.label }}</span>
|
|
|
- </div>
|
|
|
- <!--树组件,操作菜单-->
|
|
|
- <div class="menu-icon" :class="node.showTreeMenu?'show':''" v-if="node.level !== 1 && menusData.length > 0" @click.stop>
|
|
|
- <div class="cu-tree-node-popover-menu-icon" @click.prevent.stop="ElTreeLabelContextMenu($event,data,node)">
|
|
|
- <HcIcon name="menu" ui="text-2xl"/>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!--树组件,操作菜单 END-->
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </ElTree>
|
|
|
- <!--右键菜单-->
|
|
|
- <HcContextMenu ref="contextMenuRef" :datas="menusData" @item-click="handleMenuSelect" v-if="menusData.length > 0">
|
|
|
- <template #mark="{item}">
|
|
|
- <HcIcon :name="item.icon" :fill="treeRefData?.isFirst" class="menu-item-icon"/>
|
|
|
- <span class="menu-item-name">{{treeRefData?.isFirst ? '取消标记为首件' : '标记为首件'}}</span>
|
|
|
- </template>
|
|
|
- <template #sort="{item}">
|
|
|
- <HcIcon :name="item.icon" :line="false" class="menu-item-icon"/>
|
|
|
- <span class="menu-item-name">{{item.label}}</span>
|
|
|
- </template>
|
|
|
- </HcContextMenu>
|
|
|
+ <ElTree class="hc-tree-node tree-line" :class="ui" ref="ElTreeRef" :props="ElTreeProps" :data="datas" show-checkbox accordion node-key="primaryKeyId" :indent="0" @check="ElTreeCheckChange"></ElTree>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import {ref,watch} from "vue";
|
|
|
-import {getArrValue,getObjValue} from "vue-utils-plus"
|
|
|
//参数
|
|
|
const props = defineProps({
|
|
|
- menus: {
|
|
|
- type: Array,
|
|
|
- default: () => ([])
|
|
|
+ ui: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
},
|
|
|
datas: {
|
|
|
type: Array,
|
|
|
default: () => ([])
|
|
|
},
|
|
|
- autoExpandKeys: {
|
|
|
- type: Array,
|
|
|
- default: () => ([])
|
|
|
- },
|
|
|
- isMark: {
|
|
|
- type: Boolean,
|
|
|
- default: false
|
|
|
- },
|
|
|
- idPrefix: {
|
|
|
- type: String,
|
|
|
- default: 'tree-data-'
|
|
|
- },
|
|
|
- isAutoKeys: {
|
|
|
- type: Boolean,
|
|
|
- default: true
|
|
|
- },
|
|
|
- isAutoClick: {
|
|
|
- type: Boolean,
|
|
|
- default: true
|
|
|
- },
|
|
|
- isColor: {
|
|
|
- type: Boolean,
|
|
|
- default: false
|
|
|
- },
|
|
|
})
|
|
|
|
|
|
//变量
|
|
|
const ElTreeRef = ref(null)
|
|
|
-const treeRefNode = ref(null)
|
|
|
-const treeRefData = ref(null)
|
|
|
+const treeData = ref(props.datas)
|
|
|
const ElTreeProps = ref({
|
|
|
label: 'title',
|
|
|
children: 'children',
|
|
|
isLeaf: 'notExsitChild'
|
|
|
})
|
|
|
-const menusData = ref(props.menus)
|
|
|
-const menuMark = ref(props.isMark)
|
|
|
-const isAutoKeys = ref(props.isAutoKeys)
|
|
|
-const TreeExpandKey = ref(props.autoExpandKeys)
|
|
|
-const idPrefix = ref(props.idPrefix);
|
|
|
|
|
|
//监听
|
|
|
watch(() => [
|
|
|
- props.menus,
|
|
|
- props.isMark,
|
|
|
- props.isAutoKeys,
|
|
|
- props.autoExpandKeys,
|
|
|
- props.idPrefix,
|
|
|
-], ([menus, isMark, AutoKeys, expandKeys, UserIdPrefix]) => {
|
|
|
- menusData.value = menus
|
|
|
- menuMark.value = isMark
|
|
|
- isAutoKeys.value = AutoKeys
|
|
|
- TreeExpandKey.value = expandKeys
|
|
|
- idPrefix.value = UserIdPrefix
|
|
|
+ props.datas,
|
|
|
+], ([ datas ]) => {
|
|
|
+ treeData.value = datas
|
|
|
})
|
|
|
|
|
|
//事件
|
|
|
-const emit = defineEmits(['menuTap','nodeTap'])
|
|
|
+const emit = defineEmits(['change'])
|
|
|
|
|
|
-//节点被点击
|
|
|
-const ElTreeClick = async (data,node) => {
|
|
|
- if (isAutoKeys.value) {
|
|
|
- let autoKeysArr = []
|
|
|
- await getNodeExpandKeys(node, autoKeysArr)
|
|
|
- const autoKeys = autoKeysArr.reverse()
|
|
|
- emit('nodeTap', {node, data, keys: autoKeys})
|
|
|
- } else {
|
|
|
- emit('nodeTap', {node, data, keys: []})
|
|
|
- }
|
|
|
+//节点勾选
|
|
|
+const ElTreeCheckChange = (data, checkeds) => {
|
|
|
+ emit('change', {data, checkeds})
|
|
|
}
|
|
|
-
|
|
|
-//处理自动展开的节点KEY
|
|
|
-const getNodeExpandKeys = async (node, newKeys) => {
|
|
|
- const parent = getArrValue(node?.parent)
|
|
|
- const nodeData = getObjValue(node?.data);
|
|
|
- const primaryKeyId = nodeData?.primaryKeyId ?? ''
|
|
|
- if (primaryKeyId) {
|
|
|
- newKeys.push(primaryKeyId)
|
|
|
- await getNodeExpandKeys(parent, newKeys)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//鼠标右键事件
|
|
|
-const contextMenuRef = ref(null)
|
|
|
-const ElTreeLabelContextMenu = (e,data,node) => {
|
|
|
- const rows = menusData.value || [];
|
|
|
- if (node.level !== 1 && rows.length > 0) {
|
|
|
- e.preventDefault();
|
|
|
- treeRefNode.value = node;
|
|
|
- treeRefData.value = data;
|
|
|
- //展开菜单
|
|
|
- contextMenuRef.value?.showMenu(e)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//鼠标右键菜单被点击
|
|
|
-const handleMenuSelect = ({key}) => {
|
|
|
- const node = treeRefNode.value;
|
|
|
- const data = treeRefData.value;
|
|
|
- //如果为标记菜单
|
|
|
- if (key === 'mark' && menuMark.value) {
|
|
|
- if (data.isFirst === true) {
|
|
|
- emit('menuTap', {key: 'cancel_mark', node, data})
|
|
|
- } else {
|
|
|
- emit('menuTap', {key: 'mark', node, data})
|
|
|
- }
|
|
|
- } else {
|
|
|
- emit('menuTap', {key, node, data})
|
|
|
- }
|
|
|
-}
|
|
|
-//设置树菜单的标记数据
|
|
|
-const setElTreeMenuMark = (keys,isFirst) => {
|
|
|
- keys.forEach(item => {
|
|
|
- //根据 data 或者 key 拿到 Tree 组件中的 node
|
|
|
- let node = ElTreeRef.value.getNode(item)
|
|
|
- if (!!node) node.data.isFirst = isFirst;
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-//设置树菜单的标记数据
|
|
|
-const removeElTreeNode = (key) => {
|
|
|
- //根据 data 或者 key 拿到 Tree 组件中的 node
|
|
|
- let node = ElTreeRef.value.getNode(key)
|
|
|
- //删除 Tree 中的一个节点,使用此方法必须设置 node-key 属性
|
|
|
- ElTreeRef.value.remove(node)
|
|
|
-}
|
|
|
-
|
|
|
-// 暴露出去
|
|
|
-defineExpose({
|
|
|
- setElTreeMenuMark,
|
|
|
- removeElTreeNode
|
|
|
-})
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-@import "../../../styles/app/tree.scss";
|
|
|
-.data-custom-tree-node {
|
|
|
- .menu-icon {
|
|
|
- position: relative;
|
|
|
- font-size: 20px;
|
|
|
- opacity: 0;
|
|
|
- pointer-events: none;
|
|
|
- transition: opacity 0.2s;
|
|
|
- .cu-tree-node-popover-menu-icon {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- }
|
|
|
- }
|
|
|
- &:hover {
|
|
|
- .menu-icon {
|
|
|
- opacity: 1;
|
|
|
- pointer-events: all;
|
|
|
- cursor: context-menu;
|
|
|
- }
|
|
|
- }
|
|
|
- .menu-icon.show {
|
|
|
- opacity: 1;
|
|
|
- pointer-events: all;
|
|
|
- cursor: context-menu;
|
|
|
- }
|
|
|
-}
|
|
|
+@import "../../../../styles/app/tree.scss";
|
|
|
</style>
|