feat(tree): add showChecked and wip workspace
This commit is contained in:
parent
8b3eaa57c8
commit
75d51b4ff8
@ -5,10 +5,15 @@
|
|||||||
:data="data"
|
:data="data"
|
||||||
:onlyIconControl="iconCtrl"
|
:onlyIconControl="iconCtrl"
|
||||||
:showLine="showLine"
|
:showLine="showLine"
|
||||||
|
:showCheckbox="showCheckbox"
|
||||||
@node-click="handleClick"
|
@node-click="handleClick"
|
||||||
>
|
>
|
||||||
</lay-tree>
|
</lay-tree>
|
||||||
<br/>
|
<br/>
|
||||||
|
是否可开启选择框:
|
||||||
|
<br/>
|
||||||
|
<lay-switch v-model="showCheckbox"></lay-switch>
|
||||||
|
<br/>
|
||||||
只能通过节点左侧图标来展开收缩:
|
只能通过节点左侧图标来展开收缩:
|
||||||
<br/>
|
<br/>
|
||||||
<lay-switch v-model="iconCtrl"></lay-switch>
|
<lay-switch v-model="iconCtrl"></lay-switch>
|
||||||
@ -25,7 +30,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue';
|
||||||
|
|
||||||
const data = ref([
|
const data = ref([
|
||||||
{
|
{
|
||||||
@ -215,11 +220,12 @@ const data = ref([
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
])
|
]);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
function handleClick(node) {
|
function handleClick(node) {
|
||||||
clickNode.value = node
|
clickNode.value = node
|
||||||
|
@ -5,19 +5,23 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import LayIcon from '../icon'
|
import LayIcon from '../icon'
|
||||||
|
import LayCheckbox from '../checkbox'
|
||||||
import { TreeNode } from '/@src/module/tree/tree.type'
|
import { TreeNode } from '/@src/module/tree/tree.type'
|
||||||
|
|
||||||
type EventType = 'icon' | 'node'
|
type EventType = 'icon' | 'node'
|
||||||
|
|
||||||
interface TreeEntityProps {
|
interface TreeEntityProps {
|
||||||
node: TreeNode
|
node: TreeNode
|
||||||
|
showCheckbox?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EmitEvent {
|
interface EmitEvent {
|
||||||
(e: 'node-click', node: TreeNode, type: EventType): void
|
(e: 'node-click', node: TreeNode, type: EventType): void
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<TreeEntityProps>()
|
const props = withDefaults(defineProps<TreeEntityProps>(), {
|
||||||
|
showCheckbox: false,
|
||||||
|
})
|
||||||
const emit = defineEmits<EmitEvent>()
|
const emit = defineEmits<EmitEvent>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,7 +49,7 @@ const nodeIconType = (node: TreeNode): string => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node Icon Click
|
* 节点Icon点击
|
||||||
* @param node
|
* @param node
|
||||||
*/
|
*/
|
||||||
function handleIconClick(node: TreeNode) {
|
function handleIconClick(node: TreeNode) {
|
||||||
@ -53,7 +57,7 @@ function handleIconClick(node: TreeNode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Node Font Click
|
* 节点点击
|
||||||
* @param node
|
* @param node
|
||||||
*/
|
*/
|
||||||
function handleNodeClick(node: TreeNode) {
|
function handleNodeClick(node: TreeNode) {
|
||||||
@ -61,12 +65,15 @@ function handleNodeClick(node: TreeNode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 递归事件
|
* 递归emit事件
|
||||||
* @param node
|
* @param node
|
||||||
|
* @param type
|
||||||
*/
|
*/
|
||||||
function innerClick(node: TreeNode, type: EventType) {
|
function innerClick(node: TreeNode, type: EventType) {
|
||||||
emit('node-click', node, type)
|
emit('node-click', node, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(props.showCheckbox)
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<template v-if="node.children && node.children.length > 0">
|
<template v-if="node.children && node.children.length > 0">
|
||||||
@ -85,11 +92,22 @@ function innerClick(node: TreeNode, type: EventType) {
|
|||||||
@click.prevent.stop="handleIconClick(node, 'icon')"
|
@click.prevent.stop="handleIconClick(node, 'icon')"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
<LayCheckbox
|
||||||
|
v-if="showCheckbox"
|
||||||
|
name="name"
|
||||||
|
skin="primary"
|
||||||
|
label="1"
|
||||||
|
:checked="true"
|
||||||
|
>
|
||||||
|
{{ node.title }}
|
||||||
|
</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')"
|
||||||
>{{ node.title }}</span
|
|
||||||
>
|
>
|
||||||
|
{{ node.title }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -102,6 +120,7 @@ function innerClick(node: TreeNode, type: EventType) {
|
|||||||
:key="index"
|
:key="index"
|
||||||
:node="item"
|
:node="item"
|
||||||
@node-click="innerClick"
|
@node-click="innerClick"
|
||||||
|
:showCheckbox="showCheckbox"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -121,11 +140,22 @@ function innerClick(node: TreeNode, type: EventType) {
|
|||||||
@click.prevent.stop="handleIconClick(node, 'icon')"
|
@click.prevent.stop="handleIconClick(node, 'icon')"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
<LayCheckbox
|
||||||
|
v-if="showCheckbox"
|
||||||
|
name="name"
|
||||||
|
skin="primary"
|
||||||
|
label="1"
|
||||||
|
:checked="true"
|
||||||
|
>
|
||||||
|
{{ node.title }}
|
||||||
|
</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')"
|
||||||
>{{ node.title }}</span
|
|
||||||
>
|
>
|
||||||
|
{{ node.title }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -57,7 +57,7 @@ interface TreeProps {
|
|||||||
* 选中的节点
|
* 选中的节点
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line vue/require-default-prop
|
// eslint-disable-next-line vue/require-default-prop
|
||||||
checkedKeys?: (string | number)[]
|
checkedKeys?: NonNullable<(string | number)[]>
|
||||||
/**
|
/**
|
||||||
* 展开的节点
|
* 展开的节点
|
||||||
*/
|
*/
|
||||||
@ -148,7 +148,8 @@ interface TreeEmits {
|
|||||||
// * @param treeNode
|
// * @param treeNode
|
||||||
// */
|
// */
|
||||||
// (e: 'node-operate', treeNode: EmitData): void
|
// (e: 'node-operate', treeNode: EmitData): void
|
||||||
(e: 'update:spreadKeys', spreadKeys: string[]): void
|
(e: 'update:spreadKeys', spreadKeys: (string | number)[]): void
|
||||||
|
(e: 'update:checkedKeys', checkedKeys: (string | number)[]): void
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<TreeProps>(), {
|
const props = withDefaults(defineProps<TreeProps>(), {
|
||||||
@ -191,6 +192,7 @@ export default {
|
|||||||
:key="node.id || index"
|
:key="node.id || index"
|
||||||
:node="node"
|
:node="node"
|
||||||
@node-click="handleNodeClick"
|
@node-click="handleNodeClick"
|
||||||
|
:showCheckbox="showCheckbox"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -63,7 +63,7 @@ export declare interface TreeProps {
|
|||||||
/**
|
/**
|
||||||
* 选中的节点
|
* 选中的节点
|
||||||
*/
|
*/
|
||||||
checkedKeys?: (string | number)[]
|
checkedKeys?: NonNullable<(string | number)[]>
|
||||||
/**
|
/**
|
||||||
* 展开的节点
|
* 展开的节点
|
||||||
*/
|
*/
|
||||||
@ -155,6 +155,7 @@ export declare interface TreeEmits {
|
|||||||
* @param spreadKeys
|
* @param spreadKeys
|
||||||
*/
|
*/
|
||||||
(e: 'update:spreadKeys', spreadKeys: (string | number)[]): void
|
(e: 'update:spreadKeys', spreadKeys: (string | number)[]): void
|
||||||
|
(e: 'update:checkedKeys', checkedKeys: (string | number)[]): void
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TreeExpose {
|
export interface TreeExpose {
|
||||||
@ -182,7 +183,8 @@ export type UseTreeData = (
|
|||||||
props: TreeProps,
|
props: TreeProps,
|
||||||
emit: TreeEmits
|
emit: TreeEmits
|
||||||
) => {
|
) => {
|
||||||
innerTreeData: Ref<UnwrapRef<TreeData[]>>
|
innerTreeData: Ref<UnwrapRef<TreeNode[]>>
|
||||||
|
checkedKeys: WritableComputedRef<(string | number)[]>
|
||||||
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
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
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'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加父级parentId
|
* 添加父级parentId
|
||||||
* @param data
|
* @param data
|
||||||
* @param parentId
|
* @param parentId
|
||||||
|
* @param checkedKeys
|
||||||
*/
|
*/
|
||||||
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,7 +23,7 @@ export const generatorTreeData = (
|
|||||||
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)
|
inner.children = generatorTreeData(item.children, item.id, checkedKeys)
|
||||||
}
|
}
|
||||||
innerTreeData.push(inner as TreeNode)
|
innerTreeData.push(inner as TreeNode)
|
||||||
}
|
}
|
||||||
@ -62,9 +65,13 @@ export const setParentNode = (
|
|||||||
/**
|
/**
|
||||||
* 初始化内部tree结构
|
* 初始化内部tree结构
|
||||||
* @param data
|
* @param data
|
||||||
|
* @param checkedKeys
|
||||||
*/
|
*/
|
||||||
export const initialTreeData = (data: TreeData[]): TreeNode[] => {
|
export const initialTreeData = (
|
||||||
const innerTree = generatorTreeData(data)
|
data: TreeData[],
|
||||||
|
checkedKeys: WritableComputedRef<(string | number)[]>
|
||||||
|
): TreeNode[] => {
|
||||||
|
const innerTree = generatorTreeData(data, '', checkedKeys)
|
||||||
setNextSiblings(innerTree)
|
setNextSiblings(innerTree)
|
||||||
setParentNode(innerTree)
|
setParentNode(innerTree)
|
||||||
return innerTree
|
return innerTree
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TreeData, 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 {
|
||||||
getTreeSpreadKeys,
|
getTreeSpreadKeys,
|
||||||
@ -20,15 +20,24 @@ export const useTreeData: UseTreeData = (props, emit) => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const checkedKeys = computed({
|
||||||
|
get: () => {
|
||||||
|
return props.checkedKeys!
|
||||||
|
},
|
||||||
|
set: (value: (string | number)[]) => {
|
||||||
|
emit('update:checkedKeys', value)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染的data
|
* 渲染的data
|
||||||
*/
|
*/
|
||||||
const innerTreeData = ref<TreeData[]>([])
|
const innerTreeData = ref<TreeNode[]>([])
|
||||||
watch(
|
watch(
|
||||||
() => props.data,
|
() => props.data,
|
||||||
(treeData) => {
|
(treeData) => {
|
||||||
if (treeData) {
|
if (treeData) {
|
||||||
innerTreeData.value = initialTreeData(treeData)
|
innerTreeData.value = initialTreeData(treeData, checkedKeys)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true }
|
||||||
@ -60,6 +69,7 @@ export const useTreeData: UseTreeData = (props, emit) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
spreadKeys,
|
spreadKeys,
|
||||||
|
checkedKeys,
|
||||||
innerTreeData,
|
innerTreeData,
|
||||||
updateInnerTreeData,
|
updateInnerTreeData,
|
||||||
treeWrapperClass,
|
treeWrapperClass,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user