|
@@ -1,22 +1,22 @@
|
|
<template>
|
|
<template>
|
|
<el-tree-v2
|
|
<el-tree-v2
|
|
- ref="ElTreeRef"
|
|
|
|
- :class="[ui,submitCounts?'tree-line1':'']"
|
|
|
|
- :data="datas"
|
|
|
|
|
|
+ ref="ElTreeRef"
|
|
|
|
+ :class="[ui, submitCounts ? 'tree-line1' : '', isTreeShow ? 'is-tree-show': '']"
|
|
|
|
+ :data="datas"
|
|
:props="ElTreeProps"
|
|
:props="ElTreeProps"
|
|
- class="hc-tree-node tree-line el-radio-group"
|
|
|
|
- :filter-method="filterMethod"
|
|
|
|
|
|
+ class="hc-tree-node-v2 tree-line el-radio-group"
|
|
|
|
+ :filter-method="filterMethod"
|
|
:height="treeHeight"
|
|
:height="treeHeight"
|
|
@node-click="ElTreeClick"
|
|
@node-click="ElTreeClick"
|
|
accordion
|
|
accordion
|
|
highlight-current
|
|
highlight-current
|
|
:default-expand-all="false"
|
|
:default-expand-all="false"
|
|
node-key="primaryKeyId"
|
|
node-key="primaryKeyId"
|
|
-
|
|
|
|
|
|
+ :indent="24"
|
|
@node-contextmenu="ElTreeLabelContextMenu"
|
|
@node-contextmenu="ElTreeLabelContextMenu"
|
|
>
|
|
>
|
|
<template #default="{ node, data }">
|
|
<template #default="{ node, data }">
|
|
- <div :id="`${idPrefix}${data['primaryKeyId']}`" class="data-custom-tree-node">
|
|
|
|
|
|
+ <div :id="`${idPrefix}${data['primaryKeyId']}`" class="data-custom-tree-node">
|
|
<!--树组件,节点名称-->
|
|
<!--树组件,节点名称-->
|
|
<div :class="node.level === 1?'level-name':''" class="label">
|
|
<div :class="node.level === 1?'level-name':''" class="label">
|
|
<span
|
|
<span
|
|
@@ -45,8 +45,7 @@
|
|
</template>
|
|
</template>
|
|
</el-tree-v2>
|
|
</el-tree-v2>
|
|
<!--右键菜单-->
|
|
<!--右键菜单-->
|
|
- <!--右键菜单-->
|
|
|
|
- <!-- <HcContextMenu v-if="menusData.length > 0" ref="contextMenuRef" :datas="menusData" @item-click="handleMenuSelect">
|
|
|
|
|
|
+ <HcContextMenu v-if="menusData.length > 0" ref="contextMenuRef" :datas="menusData" @closed="handleMenuClosed" @item-click="handleMenuSelect">
|
|
<template #mark="{item}">
|
|
<template #mark="{item}">
|
|
<HcIcon :fill="treeRefData?.isFirst" :name="item.icon" class="menu-item-icon"/>
|
|
<HcIcon :fill="treeRefData?.isFirst" :name="item.icon" class="menu-item-icon"/>
|
|
<span class="menu-item-name">{{ treeRefData?.isFirst ? '取消标记为首件' : '标记为首件' }}</span>
|
|
<span class="menu-item-name">{{ treeRefData?.isFirst ? '取消标记为首件' : '标记为首件' }}</span>
|
|
@@ -55,19 +54,30 @@
|
|
<HcIcon :line="false" :name="item.icon" class="menu-item-icon"/>
|
|
<HcIcon :line="false" :name="item.icon" class="menu-item-icon"/>
|
|
<span class="menu-item-name">{{ item.label }}</span>
|
|
<span class="menu-item-name">{{ item.label }}</span>
|
|
</template>
|
|
</template>
|
|
- </HcContextMenu> -->
|
|
|
|
|
|
+ </HcContextMenu>
|
|
|
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
<script setup>
|
|
-import {ref, watch, nextTick} from "vue";
|
|
|
|
|
|
+import {ref, watch, nextTick, onMounted, onUnmounted} from "vue";
|
|
import {getTreeNodeType} from '~uti/utils';
|
|
import {getTreeNodeType} from '~uti/utils';
|
|
|
|
+import { ElTreeV2 } from 'z-element-plus'
|
|
|
|
+import {isNullES} from "js-fast-way";
|
|
|
|
+
|
|
//参数
|
|
//参数
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
ui: {
|
|
ui: {
|
|
type: String,
|
|
type: String,
|
|
default: ''
|
|
default: ''
|
|
},
|
|
},
|
|
|
|
+ isMark: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
|
|
+ menus: {
|
|
|
|
+ type: Array,
|
|
|
|
+ default: () => ([])
|
|
|
|
+ },
|
|
height: {
|
|
height: {
|
|
type: [Number, String],
|
|
type: [Number, String],
|
|
default: 0
|
|
default: 0
|
|
@@ -90,7 +100,7 @@ const props = defineProps({
|
|
},
|
|
},
|
|
idPrefix: {
|
|
idPrefix: {
|
|
type: String,
|
|
type: String,
|
|
- default: 'tree-data-'
|
|
|
|
|
|
+ default: 'tree-data-v2-'
|
|
},
|
|
},
|
|
isColor: {
|
|
isColor: {
|
|
type: Boolean,
|
|
type: Boolean,
|
|
@@ -100,6 +110,10 @@ const props = defineProps({
|
|
type: Boolean,
|
|
type: Boolean,
|
|
default: true
|
|
default: true
|
|
},
|
|
},
|
|
|
|
+ isShow: {
|
|
|
|
+ type: Boolean,
|
|
|
|
+ default: false
|
|
|
|
+ },
|
|
})
|
|
})
|
|
|
|
|
|
//变量
|
|
//变量
|
|
@@ -110,50 +124,53 @@ const ElTreeProps = ref({
|
|
children: 'children',
|
|
children: 'children',
|
|
})
|
|
})
|
|
const treeHeight = ref(0)
|
|
const treeHeight = ref(0)
|
|
-
|
|
|
|
|
|
+const menuMark = ref(props.isMark)
|
|
const isSubmitCounts = ref(props.submitCounts);
|
|
const isSubmitCounts = ref(props.submitCounts);
|
|
const searchInfo = ref(props.searchTreeVal)
|
|
const searchInfo = ref(props.searchTreeVal)
|
|
const idPrefix = ref(props.idPrefix);
|
|
const idPrefix = ref(props.idPrefix);
|
|
const menusData = ref(props.menus)
|
|
const menusData = ref(props.menus)
|
|
const isAutoKeys = ref(props.isAutoKeys)
|
|
const isAutoKeys = ref(props.isAutoKeys)
|
|
const treeRefData = ref(null)
|
|
const treeRefData = ref(null)
|
|
-
|
|
|
|
|
|
+const isTreeShow = ref(props.isShow)
|
|
|
|
|
|
//监听
|
|
//监听
|
|
watch(() => [
|
|
watch(() => [
|
|
props.height,
|
|
props.height,
|
|
props.submitCounts,
|
|
props.submitCounts,
|
|
- props.searchTreeVal,
|
|
|
|
- props.datas,
|
|
|
|
- props.ElTreeLoadNode,
|
|
|
|
props.idPrefix,
|
|
props.idPrefix,
|
|
props.menus,
|
|
props.menus,
|
|
props.isAutoKeys,
|
|
props.isAutoKeys,
|
|
-], ([height, submitCounts, searchTreeVal,UserIdPrefix,menus,AutoKeys]) => {
|
|
|
|
- console.log('height', height)
|
|
|
|
|
|
+ props.isMark,
|
|
|
|
+ props.isShow,
|
|
|
|
+], ([height, submitCounts,UserIdPrefix,menus,AutoKeys,isMark, isShow]) => {
|
|
treeHeight.value = height
|
|
treeHeight.value = height
|
|
isSubmitCounts.value = submitCounts
|
|
isSubmitCounts.value = submitCounts
|
|
- searchInfo.value = searchTreeVal
|
|
|
|
idPrefix.value = UserIdPrefix
|
|
idPrefix.value = UserIdPrefix
|
|
menusData.value = menus
|
|
menusData.value = menus
|
|
isAutoKeys.value = AutoKeys
|
|
isAutoKeys.value = AutoKeys
|
|
|
|
+ menuMark.value = isMark
|
|
|
|
+ isTreeShow.value = isShow
|
|
})
|
|
})
|
|
|
|
|
|
-watch(searchInfo, (val) => {
|
|
|
|
- if (val) {
|
|
|
|
- nextTick(() => {
|
|
|
|
-
|
|
|
|
- ElTreeRef?.value.filter(val)
|
|
|
|
- })
|
|
|
|
|
|
+watch(() => [
|
|
|
|
+ props.searchTreeVal,
|
|
|
|
+], ([val]) => {
|
|
|
|
+ searchInfo.value = val
|
|
|
|
+ if (val) {
|
|
|
|
+ nextTick(() => {
|
|
|
|
+ ElTreeRef?.value.filter(val)
|
|
|
|
+ })
|
|
|
|
+ } else {
|
|
|
|
+ emit('changeSearch')
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
|
|
- } else {
|
|
|
|
- emit('changeSearch')
|
|
|
|
- }
|
|
|
|
|
|
|
|
- },
|
|
|
|
|
|
+onMounted(() => {
|
|
|
|
+ getOffsetHeight()
|
|
|
|
+ windowResize()
|
|
|
|
+})
|
|
|
|
|
|
- {immediate: true}
|
|
|
|
-)
|
|
|
|
//事件
|
|
//事件
|
|
const emit = defineEmits(['menuTap', 'nodeTap', 'changeSearch', 'changetreelaod'])
|
|
const emit = defineEmits(['menuTap', 'nodeTap', 'changeSearch', 'changetreelaod'])
|
|
|
|
|
|
@@ -169,6 +186,7 @@ const getNodeExpandKeys = async (node, newKeys) => {
|
|
}
|
|
}
|
|
//节点被点击
|
|
//节点被点击
|
|
const ElTreeClick = async (data, node) => {
|
|
const ElTreeClick = async (data, node) => {
|
|
|
|
+ console.log(node)
|
|
if (isAutoKeys.value) {
|
|
if (isAutoKeys.value) {
|
|
let autoKeysArr = []
|
|
let autoKeysArr = []
|
|
await getNodeExpandKeys(node, autoKeysArr)
|
|
await getNodeExpandKeys(node, autoKeysArr)
|
|
@@ -178,21 +196,21 @@ const ElTreeClick = async (data, node) => {
|
|
emit('nodeTap', {node, data, keys: []})
|
|
emit('nodeTap', {node, data, keys: []})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
const getReturnNode = (node, _array, value) => {
|
|
const getReturnNode = (node, _array, value) => {
|
|
- let isPass = node && node.title && node.title.indexOf(value) !== -1;
|
|
|
|
-
|
|
|
|
|
|
+ let isPass = node.data && node.data.title && node.data.title.indexOf(value) !== -1;
|
|
isPass ? _array.push(isPass) : '';
|
|
isPass ? _array.push(isPass) : '';
|
|
if (!isPass && node.level != 1 && node.parent) {
|
|
if (!isPass && node.level != 1 && node.parent) {
|
|
getReturnNode(node.parent, _array, value);
|
|
getReturnNode(node.parent, _array, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//筛选树节点
|
|
//筛选树节点
|
|
-const filterMethod = (query, node) => {
|
|
|
|
|
|
+const filterMethod = (query,data) => {
|
|
if (!query) {
|
|
if (!query) {
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
- let level = node.title;
|
|
|
|
let _array = [];//这里使用数组存储 只是为了存储值。
|
|
let _array = [];//这里使用数组存储 只是为了存储值。
|
|
|
|
+ let node=ElTreeRef?.value.getNode(data.primaryKeyId)
|
|
getReturnNode(node, _array, query);
|
|
getReturnNode(node, _array, query);
|
|
let result = false;
|
|
let result = false;
|
|
_array.forEach((item) => {
|
|
_array.forEach((item) => {
|
|
@@ -202,16 +220,18 @@ const filterMethod = (query, node) => {
|
|
emit('changetreelaod', false)
|
|
emit('changetreelaod', false)
|
|
}, 1000)
|
|
}, 1000)
|
|
return result;
|
|
return result;
|
|
-
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
//鼠标右键事件
|
|
//鼠标右键事件
|
|
const contextMenuRef = ref(null)
|
|
const contextMenuRef = ref(null)
|
|
|
|
+const treeRefNode = ref(null)
|
|
const ElTreeLabelContextMenu = (e, data, node) => {
|
|
const ElTreeLabelContextMenu = (e, data, node) => {
|
|
const rows = menusData.value || [];
|
|
const rows = menusData.value || [];
|
|
if (node.level !== 1 && rows.length > 0) {
|
|
if (node.level !== 1 && rows.length > 0) {
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
treeRefNode.value = node;
|
|
treeRefNode.value = node;
|
|
treeRefData.value = data;
|
|
treeRefData.value = data;
|
|
|
|
+ node.showTreeMenu = true
|
|
//展开菜单
|
|
//展开菜单
|
|
contextMenuRef.value?.showMenu(e)
|
|
contextMenuRef.value?.showMenu(e)
|
|
}
|
|
}
|
|
@@ -230,6 +250,7 @@ const handleMenuSelect = async ({key}) => {
|
|
} else {
|
|
} else {
|
|
// emit('menuTap', {key, node, data})
|
|
// emit('menuTap', {key, node, data})
|
|
if (isAutoKeys.value) {
|
|
if (isAutoKeys.value) {
|
|
|
|
+ console.log(11111);
|
|
let autoKeysArr = []
|
|
let autoKeysArr = []
|
|
await getNodeExpandKeys(node, autoKeysArr)
|
|
await getNodeExpandKeys(node, autoKeysArr)
|
|
const autoKeys = autoKeysArr.reverse()
|
|
const autoKeys = autoKeysArr.reverse()
|
|
@@ -237,6 +258,15 @@ const handleMenuSelect = async ({key}) => {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+const handleMenuClosed = () => {
|
|
|
|
+ const node = treeRefNode.value;
|
|
|
|
+ if (!isNullES(node)) {
|
|
|
|
+ treeRefNode.value['showTreeMenu'] = false
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
//设置树菜单的标记数据
|
|
//设置树菜单的标记数据
|
|
const setElTreeMenuMark = (keys, isFirst) => {
|
|
const setElTreeMenuMark = (keys, isFirst) => {
|
|
keys.forEach(item => {
|
|
keys.forEach(item => {
|
|
@@ -252,6 +282,31 @@ const removeElTreeNode = (key) => {
|
|
//删除 Tree 中的一个节点,使用此方法必须设置 node-key 属性
|
|
//删除 Tree 中的一个节点,使用此方法必须设置 node-key 属性
|
|
ElTreeRef.value.remove(node)
|
|
ElTreeRef.value.remove(node)
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+//监听浏览器窗口变化
|
|
|
|
+const windowResize = () => {
|
|
|
|
+ window.addEventListener("resize", resizeEvent);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const resizeEvent = () => {
|
|
|
|
+ window.requestAnimationFrame(() => {
|
|
|
|
+ getOffsetHeight()
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const getOffsetHeight = () => {
|
|
|
|
+ try {
|
|
|
|
+ treeHeight.value = document.getElementById('hc-tree-scrollbar').offsetHeight;
|
|
|
|
+ } catch {
|
|
|
|
+ console.log('hc-tree-scrollbar 元素,不存在,获取高度失败')
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+//被卸载
|
|
|
|
+onUnmounted(() => {
|
|
|
|
+ window.removeEventListener("resize", resizeEvent);
|
|
|
|
+})
|
|
|
|
+
|
|
// 暴露出去
|
|
// 暴露出去
|
|
defineExpose({
|
|
defineExpose({
|
|
setElTreeMenuMark,
|
|
setElTreeMenuMark,
|
|
@@ -282,15 +337,15 @@ defineExpose({
|
|
font-size: 14px;
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
.menu-icon1 {
|
|
.menu-icon1 {
|
|
- position: unset;
|
|
|
|
|
|
+ position: relative;
|
|
vertical-align: bottom;
|
|
vertical-align: bottom;
|
|
display: inline-block;
|
|
display: inline-block;
|
|
|
|
+ width: 0;
|
|
|
|
+ right: -45px;
|
|
|
|
+ border-radius: 2px;
|
|
pointer-events: none;
|
|
pointer-events: none;
|
|
- transition: opacity 0.2s;
|
|
|
|
- opacity: 0;
|
|
|
|
- right: 0;
|
|
|
|
background: rgba(255, 255, 255, 0.25);
|
|
background: rgba(255, 255, 255, 0.25);
|
|
- border-radius: 2px;
|
|
|
|
|
|
+ transition: width 0.2s;
|
|
.cu-tree-node-popover-menu-icon {
|
|
.cu-tree-node-popover-menu-icon {
|
|
display: flex;
|
|
display: flex;
|
|
align-items: center;
|
|
align-items: center;
|
|
@@ -299,28 +354,35 @@ defineExpose({
|
|
}
|
|
}
|
|
&:hover {
|
|
&:hover {
|
|
.menu-icon1 {
|
|
.menu-icon1 {
|
|
- opacity: 1;
|
|
|
|
|
|
+ right: 0;
|
|
|
|
+ width: 24px;
|
|
pointer-events: all;
|
|
pointer-events: all;
|
|
cursor: context-menu;
|
|
cursor: context-menu;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.menu-icon1.show {
|
|
.menu-icon1.show {
|
|
- opacity: 1;
|
|
|
|
|
|
+ right: 0;
|
|
|
|
+ width: 24px;
|
|
pointer-events: all;
|
|
pointer-events: all;
|
|
cursor: context-menu;
|
|
cursor: context-menu;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|
|
<style lang="scss">
|
|
<style lang="scss">
|
|
-
|
|
|
|
-.el-tree.hc-tree-node .el-tree-node {
|
|
|
|
- white-space: nowrap;
|
|
|
|
- overflow: hidden;
|
|
|
|
- text-overflow: ellipsis;
|
|
|
|
- .el-tree-node_content {
|
|
|
|
|
|
+.hc-tree-node-v2.el-tree {
|
|
|
|
+ display: none;
|
|
|
|
+ .el-tree-node {
|
|
white-space: nowrap;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
text-overflow: ellipsis;
|
|
|
|
+ .el-tree-node_content {
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ &.is-tree-show {
|
|
|
|
+ display: block;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|