feat(tree): 完成树形组件复选框功能
This commit is contained in:
parent
c559a2d74a
commit
7caf70281c
@ -60,6 +60,7 @@ module.exports = {
|
|||||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||||
'vue/one-component-per-file': 'off',
|
'vue/one-component-per-file': 'off',
|
||||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
|
'vue/no-mutating-props': 'off',
|
||||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
:onlyIconControl="iconCtrl"
|
:onlyIconControl="iconCtrl"
|
||||||
:showLine="showLine"
|
:showLine="showLine"
|
||||||
:showCheckbox="showCheckbox"
|
:showCheckbox="showCheckbox"
|
||||||
|
v-model:checkedKeys="checkedKeys"
|
||||||
@node-click="handleClick"
|
@node-click="handleClick"
|
||||||
>
|
>
|
||||||
</lay-tree>
|
</lay-tree>
|
||||||
@ -14,6 +15,10 @@
|
|||||||
<br/>
|
<br/>
|
||||||
<lay-switch v-model="showCheckbox"></lay-switch>
|
<lay-switch v-model="showCheckbox"></lay-switch>
|
||||||
<br/>
|
<br/>
|
||||||
|
checkedKeys:
|
||||||
|
<pre>
|
||||||
|
{{ checkedKeys }}
|
||||||
|
</pre>
|
||||||
只能通过节点左侧图标来展开收缩:
|
只能通过节点左侧图标来展开收缩:
|
||||||
<br/>
|
<br/>
|
||||||
<lay-switch v-model="iconCtrl"></lay-switch>
|
<lay-switch v-model="iconCtrl"></lay-switch>
|
||||||
@ -25,207 +30,178 @@
|
|||||||
当前点击的节点:
|
当前点击的节点:
|
||||||
<br/>
|
<br/>
|
||||||
<pre>
|
<pre>
|
||||||
{{ clickNode }}
|
{{ clickNode }}
|
||||||
</pre>
|
</pre>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
|
||||||
const data = ref([
|
const data = ref([{
|
||||||
{
|
title: '一级1',
|
||||||
title: '一级1',
|
id: 1,
|
||||||
id: 1,
|
field: 'name1',
|
||||||
field: 'name1',
|
checked: true,
|
||||||
checked: true,
|
spread: true,
|
||||||
spread: true,
|
children: [{
|
||||||
children: [
|
title: '二级1-1 可允许跳转',
|
||||||
{
|
id: 3,
|
||||||
title: '二级1-1 可允许跳转',
|
field: 'name11',
|
||||||
id: 3,
|
href: 'https://www.layui.com/',
|
||||||
field: 'name11',
|
children: [{
|
||||||
href: 'https://www.layui.com/',
|
title: '三级1-1-3',
|
||||||
children: [
|
id: 23,
|
||||||
{
|
field: '',
|
||||||
title: '三级1-1-3',
|
children: [{
|
||||||
id: 23,
|
title: '四级1-1-3-1',
|
||||||
field: '',
|
id: 24,
|
||||||
children: [
|
field: '',
|
||||||
{
|
children: [{
|
||||||
title: '四级1-1-3-1',
|
title: '五级1-1-3-1-1',
|
||||||
id: 24,
|
id: 30,
|
||||||
field: '',
|
field: ''
|
||||||
children: [
|
},
|
||||||
{
|
{
|
||||||
title: '五级1-1-3-1-1',
|
title: '五级1-1-3-1-2',
|
||||||
id: 30,
|
id: 31,
|
||||||
field: '',
|
field: ''
|
||||||
},
|
}]
|
||||||
{
|
}]
|
||||||
title: '五级1-1-3-1-2',
|
},
|
||||||
id: 31,
|
{
|
||||||
field: '',
|
title: '三级1-1-1',
|
||||||
},
|
id: 7,
|
||||||
],
|
field: '',
|
||||||
},
|
children: [{
|
||||||
],
|
title: '四级1-1-1-1 可允许跳转',
|
||||||
},
|
id: 15,
|
||||||
{
|
field: '',
|
||||||
title: '三级1-1-1',
|
href: 'https://www.layui.com/doc/'
|
||||||
id: 7,
|
}]
|
||||||
field: '',
|
},
|
||||||
children: [
|
{
|
||||||
{
|
title: '三级1-1-2',
|
||||||
title: '四级1-1-1-1 可允许跳转',
|
id: 8,
|
||||||
id: 15,
|
field: '',
|
||||||
field: '',
|
children: [{
|
||||||
href: 'https://www.layui.com/doc/',
|
title: '四级1-1-2-1',
|
||||||
},
|
id: 32,
|
||||||
],
|
field: ''
|
||||||
},
|
}]
|
||||||
{
|
}]
|
||||||
title: '三级1-1-2',
|
},
|
||||||
id: 8,
|
{
|
||||||
field: '',
|
title: '二级1-2',
|
||||||
children: [
|
id: 4,
|
||||||
{
|
spread: true,
|
||||||
title: '四级1-1-2-1',
|
children: [{
|
||||||
id: 32,
|
title: '三级1-2-1',
|
||||||
field: '',
|
id: 9,
|
||||||
},
|
field: '',
|
||||||
],
|
disabled: true
|
||||||
},
|
},
|
||||||
],
|
{
|
||||||
},
|
title: '三级1-2-2',
|
||||||
{
|
id: 10,
|
||||||
title: '二级1-2',
|
field: ''
|
||||||
id: 4,
|
}]
|
||||||
spread: true,
|
},
|
||||||
children: [
|
{
|
||||||
{
|
title: '二级1-3',
|
||||||
title: '三级1-2-1',
|
id: 20,
|
||||||
id: 9,
|
field: '',
|
||||||
field: '',
|
children: [{
|
||||||
disabled: true,
|
title: '三级1-3-1',
|
||||||
},
|
id: 21,
|
||||||
{
|
field: ''
|
||||||
title: '三级1-2-2',
|
},
|
||||||
id: 10,
|
{
|
||||||
field: '',
|
title: '三级1-3-2',
|
||||||
},
|
id: 22,
|
||||||
],
|
field: ''
|
||||||
},
|
}]
|
||||||
{
|
}]
|
||||||
title: '二级1-3',
|
},
|
||||||
id: 20,
|
{
|
||||||
field: '',
|
title: '一级2',
|
||||||
children: [
|
id: 2,
|
||||||
{
|
field: '',
|
||||||
title: '三级1-3-1',
|
spread: true,
|
||||||
id: 21,
|
children: [{
|
||||||
field: '',
|
title: '二级2-1',
|
||||||
},
|
id: 5,
|
||||||
{
|
field: '',
|
||||||
title: '三级1-3-2',
|
spread: true,
|
||||||
id: 22,
|
children: [{
|
||||||
field: '',
|
title: '三级2-1-1',
|
||||||
},
|
id: 11,
|
||||||
],
|
field: ''
|
||||||
},
|
},
|
||||||
],
|
{
|
||||||
},
|
title: '三级2-1-2',
|
||||||
{
|
id: 12,
|
||||||
title: '一级2',
|
field: ''
|
||||||
id: 2,
|
}]
|
||||||
field: '',
|
},
|
||||||
spread: true,
|
{
|
||||||
children: [
|
title: '二级2-2',
|
||||||
{
|
id: 6,
|
||||||
title: '二级2-1',
|
field: '',
|
||||||
id: 5,
|
children: [{
|
||||||
field: '',
|
title: '三级2-2-1',
|
||||||
spread: true,
|
id: 13,
|
||||||
children: [
|
field: ''
|
||||||
{
|
},
|
||||||
title: '三级2-1-1',
|
{
|
||||||
id: 11,
|
title: '三级2-2-2',
|
||||||
field: '',
|
id: 14,
|
||||||
},
|
field: '',
|
||||||
{
|
disabled: true
|
||||||
title: '三级2-1-2',
|
}]
|
||||||
id: 12,
|
}]
|
||||||
field: '',
|
},
|
||||||
},
|
{
|
||||||
],
|
title: '一级3',
|
||||||
},
|
id: 16,
|
||||||
{
|
field: '',
|
||||||
title: '二级2-2',
|
children: [{
|
||||||
id: 6,
|
title: '二级3-1',
|
||||||
field: '',
|
id: 17,
|
||||||
children: [
|
field: '',
|
||||||
{
|
fixed: true,
|
||||||
title: '三级2-2-1',
|
children: [{
|
||||||
id: 13,
|
title: '三级3-1-1',
|
||||||
field: '',
|
id: 18,
|
||||||
},
|
field: ''
|
||||||
{
|
},
|
||||||
title: '三级2-2-2',
|
{
|
||||||
id: 14,
|
title: '三级3-1-2',
|
||||||
field: '',
|
id: 19,
|
||||||
disabled: true,
|
field: ''
|
||||||
},
|
}]
|
||||||
],
|
},
|
||||||
},
|
{
|
||||||
],
|
title: '二级3-2',
|
||||||
},
|
id: 27,
|
||||||
{
|
field: '',
|
||||||
title: '一级3',
|
children: [{
|
||||||
id: 16,
|
title: '三级3-2-1',
|
||||||
field: '',
|
id: 28,
|
||||||
children: [
|
field: ''
|
||||||
{
|
},
|
||||||
title: '二级3-1',
|
{
|
||||||
id: 17,
|
title: '三级3-2-2',
|
||||||
field: '',
|
id: 29,
|
||||||
fixed: true,
|
field: ''
|
||||||
children: [
|
}]
|
||||||
{
|
}]
|
||||||
title: '三级3-1-1',
|
}]);
|
||||||
id: 18,
|
|
||||||
field: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '三级3-1-2',
|
|
||||||
id: 19,
|
|
||||||
field: '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '二级3-2',
|
|
||||||
id: 27,
|
|
||||||
field: '',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
title: '三级3-2-1',
|
|
||||||
id: 28,
|
|
||||||
field: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '三级3-2-2',
|
|
||||||
id: 29,
|
|
||||||
field: '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const iconCtrl = ref(false);
|
const iconCtrl = ref(false);
|
||||||
const showLine = ref(true);
|
const showLine = ref(true);
|
||||||
const clickNode = ref(null);
|
const clickNode = ref(null);
|
||||||
const showCheckbox = ref(true);
|
const showCheckbox = ref(true);
|
||||||
|
const checkedKeys = ref([9, 10, 24]);
|
||||||
|
|
||||||
function handleClick(node) {
|
function handleClick(node) {
|
||||||
clickNode.value = node
|
clickNode.value = node
|
||||||
|
@ -12,7 +12,8 @@ type EventType = 'icon' | 'node'
|
|||||||
|
|
||||||
interface TreeEntityProps {
|
interface TreeEntityProps {
|
||||||
node: TreeNode
|
node: TreeNode
|
||||||
showCheckbox?: boolean
|
showCheckbox?: boolean,
|
||||||
|
updateCheckedByNode: (node: TreeNode) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EmitEvent {
|
interface EmitEvent {
|
||||||
@ -73,7 +74,14 @@ function innerClick(node: TreeNode, type: EventType) {
|
|||||||
emit('node-click', node, type)
|
emit('node-click', node, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(props.showCheckbox)
|
/**
|
||||||
|
* checkbox click
|
||||||
|
* @param arg
|
||||||
|
* @param node
|
||||||
|
*/
|
||||||
|
function handleCheckboxChange (arg: { checked: boolean, value: string }, node: TreeNode) {
|
||||||
|
props.updateCheckedByNode(node)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<template v-if="node.children && node.children.length > 0">
|
<template v-if="node.children && node.children.length > 0">
|
||||||
@ -96,13 +104,12 @@ console.log(props.showCheckbox)
|
|||||||
v-if="showCheckbox"
|
v-if="showCheckbox"
|
||||||
name="name"
|
name="name"
|
||||||
skin="primary"
|
skin="primary"
|
||||||
label="1"
|
v-model:checked="node._checked"
|
||||||
:checked="true"
|
@change="(args) => { handleCheckboxChange(args, node) }"
|
||||||
>
|
>
|
||||||
{{ node.title }}
|
<!-- {{ node.title }} || {{node.id}}-->
|
||||||
</LayCheckbox>
|
</LayCheckbox>
|
||||||
<span
|
<span
|
||||||
v-else
|
|
||||||
class="layui-tree-txt"
|
class="layui-tree-txt"
|
||||||
@click.prevent.stop="handleNodeClick(node, 'node')"
|
@click.prevent.stop="handleNodeClick(node, 'node')"
|
||||||
>
|
>
|
||||||
@ -119,8 +126,9 @@ console.log(props.showCheckbox)
|
|||||||
v-for="(item, index) in node.children"
|
v-for="(item, index) in node.children"
|
||||||
:key="index"
|
:key="index"
|
||||||
:node="item"
|
:node="item"
|
||||||
|
:show-checkbox="showCheckbox"
|
||||||
@node-click="innerClick"
|
@node-click="innerClick"
|
||||||
:showCheckbox="showCheckbox"
|
:updateCheckedByNode="updateCheckedByNode"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -145,12 +153,11 @@ console.log(props.showCheckbox)
|
|||||||
name="name"
|
name="name"
|
||||||
skin="primary"
|
skin="primary"
|
||||||
label="1"
|
label="1"
|
||||||
:checked="true"
|
v-model:checked="node._checked"
|
||||||
|
@change="(args) => { handleCheckboxChange(args, node) }"
|
||||||
>
|
>
|
||||||
{{ node.title }}
|
|
||||||
</LayCheckbox>
|
</LayCheckbox>
|
||||||
<span
|
<span
|
||||||
v-else
|
|
||||||
class="layui-tree-txt"
|
class="layui-tree-txt"
|
||||||
@click.prevent.stop="handleNodeClick(node, 'node')"
|
@click.prevent.stop="handleNodeClick(node, 'node')"
|
||||||
>
|
>
|
||||||
|
@ -163,10 +163,12 @@ const props = withDefaults(defineProps<TreeProps>(), {
|
|||||||
|
|
||||||
const emit = defineEmits<TreeEmits>()
|
const emit = defineEmits<TreeEmits>()
|
||||||
|
|
||||||
const { innerTreeData, updateInnerTreeData, treeWrapperClass } = useTreeData(
|
const {
|
||||||
props,
|
innerTreeData,
|
||||||
emit
|
updateInnerTreeData,
|
||||||
)
|
treeWrapperClass,
|
||||||
|
updateCheckedByNode,
|
||||||
|
} = useTreeData(props, emit)
|
||||||
|
|
||||||
function handleNodeClick(node: TreeNode, type: 'node' | 'icon') {
|
function handleNodeClick(node: TreeNode, type: 'node' | 'icon') {
|
||||||
// 是否只通过icon控制展开收起
|
// 是否只通过icon控制展开收起
|
||||||
@ -191,8 +193,9 @@ export default {
|
|||||||
v-for="(node, index) in innerTreeData"
|
v-for="(node, index) in innerTreeData"
|
||||||
:key="node.id || index"
|
:key="node.id || index"
|
||||||
:node="node"
|
:node="node"
|
||||||
|
:show-checkbox="showCheckbox"
|
||||||
@node-click="handleNodeClick"
|
@node-click="handleNodeClick"
|
||||||
:showCheckbox="showCheckbox"
|
:updateCheckedByNode="updateCheckedByNode"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -176,6 +176,7 @@ export interface TreeNode extends TreeData {
|
|||||||
_parentNode?: Nullable<TreeNode>
|
_parentNode?: Nullable<TreeNode>
|
||||||
_nextSibling?: Nullable<TreeNode>
|
_nextSibling?: Nullable<TreeNode>
|
||||||
_expand?: boolean
|
_expand?: boolean
|
||||||
|
_checked?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/** hook type **/
|
/** hook type **/
|
||||||
@ -188,4 +189,5 @@ export type UseTreeData = (
|
|||||||
spreadKeys: WritableComputedRef<(string | number)[]>
|
spreadKeys: WritableComputedRef<(string | number)[]>
|
||||||
treeWrapperClass: ComputedRef<Recordable>
|
treeWrapperClass: ComputedRef<Recordable>
|
||||||
updateInnerTreeData: (treeData: TreeData[], node: TreeData) => void
|
updateInnerTreeData: (treeData: TreeData[], node: TreeData) => void
|
||||||
|
updateCheckedByNode: (treeNode: TreeNode) => void
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { TreeData, TreeNode } from '/@src/module/tree/tree.type'
|
import { TreeData, TreeNode } from '/@src/module/tree/tree.type'
|
||||||
import { Nullable } from '/@src/module/type'
|
import { Nullable } from '/@src/module/type'
|
||||||
import { WritableComputedRef } from 'vue'
|
import { Ref, WritableComputedRef } from "vue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加父级parentId
|
* 添加父级parentId
|
||||||
@ -10,8 +10,7 @@ import { WritableComputedRef } from 'vue'
|
|||||||
*/
|
*/
|
||||||
export const generatorTreeData = (
|
export const generatorTreeData = (
|
||||||
data: TreeData[] | TreeNode[],
|
data: TreeData[] | TreeNode[],
|
||||||
parentId: TreeNode['parentId'] = '',
|
parentId: TreeNode['parentId'] = ''
|
||||||
checkedKeys: WritableComputedRef<(string | number)[]>
|
|
||||||
): TreeNode[] => {
|
): TreeNode[] => {
|
||||||
const innerTreeData: TreeNode[] = []
|
const innerTreeData: TreeNode[] = []
|
||||||
const len = data.length
|
const len = data.length
|
||||||
@ -20,10 +19,10 @@ export const generatorTreeData = (
|
|||||||
const inner = {
|
const inner = {
|
||||||
...item,
|
...item,
|
||||||
parentId: parentId,
|
parentId: parentId,
|
||||||
spread: item.spread || false,
|
spread: item.spread || false
|
||||||
}
|
}
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
inner.children = generatorTreeData(item.children, item.id, checkedKeys)
|
inner.children = generatorTreeData(item.children, item.id)
|
||||||
}
|
}
|
||||||
innerTreeData.push(inner as TreeNode)
|
innerTreeData.push(inner as TreeNode)
|
||||||
}
|
}
|
||||||
@ -71,9 +70,10 @@ export const initialTreeData = (
|
|||||||
data: TreeData[],
|
data: TreeData[],
|
||||||
checkedKeys: WritableComputedRef<(string | number)[]>
|
checkedKeys: WritableComputedRef<(string | number)[]>
|
||||||
): TreeNode[] => {
|
): TreeNode[] => {
|
||||||
const innerTree = generatorTreeData(data, '', checkedKeys)
|
const innerTree = generatorTreeData(data, '')
|
||||||
setNextSiblings(innerTree)
|
setNextSiblings(innerTree)
|
||||||
setParentNode(innerTree)
|
setParentNode(innerTree)
|
||||||
|
patchCheckedKeys(innerTree, checkedKeys)
|
||||||
return innerTree
|
return innerTree
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,3 +123,88 @@ export const getEmitNode = (
|
|||||||
}
|
}
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checkedKes分发到node
|
||||||
|
* @param tree
|
||||||
|
* @param checkedKeys
|
||||||
|
* @param checked
|
||||||
|
*/
|
||||||
|
export const patchCheckedKeys = (tree: TreeNode[], checkedKeys: WritableComputedRef<(string | number)[]>, checked = false): void => {
|
||||||
|
if (!checkedKeys.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const len = tree.length
|
||||||
|
for (let i = 0; i < len; i++){
|
||||||
|
tree[i]._checked = checked
|
||||||
|
const node = tree[i]
|
||||||
|
// 该节点是checked
|
||||||
|
if (checkedKeys.value.indexOf(node.id) > -1) {
|
||||||
|
node._checked = true
|
||||||
|
if (node.children && node.children.length > 0) {
|
||||||
|
patchCheckedKeys(node.children, checkedKeys, true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (node.children && node.children.length > 0) {
|
||||||
|
patchCheckedKeys(node.children, checkedKeys, false)
|
||||||
|
// 判断children是否为都选中,如果是都选中的情况下,父组件也得是选中
|
||||||
|
const allChildrenChecked = node.children.every(it => it._checked)
|
||||||
|
if (allChildrenChecked) {
|
||||||
|
node._checked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateChildren(data: TreeNode[], flag: boolean) {
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
data[i]._checked = flag
|
||||||
|
if (data[i].children && data[i].children.length > 0) {
|
||||||
|
updateChildren(data[i].children, flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新树
|
||||||
|
* @param data
|
||||||
|
* @param clickNode
|
||||||
|
* @param parentNode
|
||||||
|
*/
|
||||||
|
export function updateInnerTreeDataChecked(data: TreeNode[], clickNode: TreeNode, parentNode?: TreeNode) {
|
||||||
|
const len = data.length
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const currentNode = data[i]
|
||||||
|
// 找到当前更新的节点
|
||||||
|
if (currentNode.id === clickNode.id) {
|
||||||
|
// 如果当前节点有子节点,更新子节点
|
||||||
|
if (currentNode.children && currentNode.children.length > 0) {
|
||||||
|
updateChildren(data[i].children, currentNode._checked!)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (currentNode.children && currentNode.children.length > 0) {
|
||||||
|
updateInnerTreeDataChecked(currentNode.children, clickNode, currentNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 当前节点有选中,父节点一定选中
|
||||||
|
if (currentNode.children && currentNode.children.length > 0) {
|
||||||
|
currentNode._checked = currentNode.children.some(it => it._checked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCheckedKeys(tree: TreeNode[]): (string | number)[] {
|
||||||
|
let keys: (string | number) [] = []
|
||||||
|
const len = tree.length
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const current = tree[i]
|
||||||
|
if (current._checked) {
|
||||||
|
keys.push(current.id)
|
||||||
|
if (current.children && current.children.length > 0) {
|
||||||
|
keys = [...keys, ...getCheckedKeys(current.children)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { TreeData, TreeNode, UseTreeData } from '/@src/module/tree/tree.type'
|
import { TreeData, TreeNode, UseTreeData } from '/@src/module/tree/tree.type'
|
||||||
import { computed, ref, unref, watch } from 'vue'
|
import { computed, ref, unref, watch } from 'vue'
|
||||||
import {
|
import {
|
||||||
|
getCheckedKeys,
|
||||||
getTreeSpreadKeys,
|
getTreeSpreadKeys,
|
||||||
initialTreeData,
|
initialTreeData, updateInnerTreeDataChecked
|
||||||
} from '/@src/module/tree/treeHelper'
|
} from "/@src/module/tree/treeHelper";
|
||||||
import { Recordable } from '/@src/module/type'
|
import { Recordable } from '/@src/module/type'
|
||||||
|
|
||||||
export const useTreeData: UseTreeData = (props, emit) => {
|
export const useTreeData: UseTreeData = (props, emit) => {
|
||||||
@ -43,6 +44,16 @@ export const useTreeData: UseTreeData = (props, emit) => {
|
|||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watch innerTreeDate to emit checkedKeys
|
||||||
|
* @param treeData
|
||||||
|
* @param node
|
||||||
|
*/
|
||||||
|
watch(innerTreeData, tree => {
|
||||||
|
const emitCheckedKeys = getCheckedKeys(tree)
|
||||||
|
checkedKeys.value = emitCheckedKeys
|
||||||
|
}, { deep: true })
|
||||||
|
|
||||||
function updateInnerTreeData(treeData: TreeData[], node: TreeData): void {
|
function updateInnerTreeData(treeData: TreeData[], node: TreeData): void {
|
||||||
for (let i = 0; i < treeData.length; i++) {
|
for (let i = 0; i < treeData.length; i++) {
|
||||||
if (treeData[i].id === node.id) {
|
if (treeData[i].id === node.id) {
|
||||||
@ -67,11 +78,20 @@ export const useTreeData: UseTreeData = (props, emit) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新checked状态到node中
|
||||||
|
* @param node
|
||||||
|
*/
|
||||||
|
function updateCheckedByNode (node: TreeNode) {
|
||||||
|
updateInnerTreeDataChecked(innerTreeData.value, node)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
spreadKeys,
|
spreadKeys,
|
||||||
checkedKeys,
|
checkedKeys,
|
||||||
innerTreeData,
|
innerTreeData,
|
||||||
updateInnerTreeData,
|
updateInnerTreeData,
|
||||||
treeWrapperClass,
|
treeWrapperClass,
|
||||||
|
updateCheckedByNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user