feat(tree): 完成树形组件复选框功能

This commit is contained in:
落小梅 2021-10-14 16:38:25 +08:00
parent 7caf70281c
commit 3193684a4a
4 changed files with 49 additions and 25 deletions

View File

@ -12,7 +12,7 @@ type EventType = 'icon' | 'node'
interface TreeEntityProps { interface TreeEntityProps {
node: TreeNode node: TreeNode
showCheckbox?: boolean, showCheckbox?: boolean
updateCheckedByNode: (node: TreeNode) => void updateCheckedByNode: (node: TreeNode) => void
} }
@ -79,7 +79,10 @@ function innerClick(node: TreeNode, type: EventType) {
* @param arg * @param arg
* @param node * @param node
*/ */
function handleCheckboxChange (arg: { checked: boolean, value: string }, node: TreeNode) { function handleCheckboxChange(
arg: { checked: boolean; value: string },
node: TreeNode
) {
props.updateCheckedByNode(node) props.updateCheckedByNode(node)
} }
</script> </script>
@ -102,10 +105,14 @@ function handleCheckboxChange (arg: { checked: boolean, value: string }, node: T
</span> </span>
<LayCheckbox <LayCheckbox
v-if="showCheckbox" v-if="showCheckbox"
v-model:checked="node._checked"
name="name" name="name"
skin="primary" skin="primary"
v-model:checked="node._checked" @change="
@change="(args) => { handleCheckboxChange(args, node) }" (args) => {
handleCheckboxChange(args, node)
}
"
> >
<!-- {{ node.title }} || {{node.id}}--> <!-- {{ node.title }} || {{node.id}}-->
</LayCheckbox> </LayCheckbox>
@ -127,8 +134,8 @@ function handleCheckboxChange (arg: { checked: boolean, value: string }, node: T
:key="index" :key="index"
:node="item" :node="item"
:show-checkbox="showCheckbox" :show-checkbox="showCheckbox"
:update-checked-by-node="updateCheckedByNode"
@node-click="innerClick" @node-click="innerClick"
:updateCheckedByNode="updateCheckedByNode"
/> />
</div> </div>
</div> </div>
@ -150,11 +157,15 @@ function handleCheckboxChange (arg: { checked: boolean, value: string }, node: T
</span> </span>
<LayCheckbox <LayCheckbox
v-if="showCheckbox" v-if="showCheckbox"
v-model:checked="node._checked"
name="name" name="name"
skin="primary" skin="primary"
label="1" label="1"
v-model:checked="node._checked" @change="
@change="(args) => { handleCheckboxChange(args, node) }" (args) => {
handleCheckboxChange(args, node)
}
"
> >
</LayCheckbox> </LayCheckbox>
<span <span

View File

@ -194,8 +194,8 @@ export default {
:key="node.id || index" :key="node.id || index"
:node="node" :node="node"
:show-checkbox="showCheckbox" :show-checkbox="showCheckbox"
:update-checked-by-node="updateCheckedByNode"
@node-click="handleNodeClick" @node-click="handleNodeClick"
:updateCheckedByNode="updateCheckedByNode"
/> />
</div> </div>
</template> </template>

View File

@ -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 { Ref, WritableComputedRef } from "vue"; import { Ref, WritableComputedRef } from 'vue'
/** /**
* parentId * parentId
@ -19,7 +19,7 @@ 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) inner.children = generatorTreeData(item.children, item.id)
@ -130,7 +130,11 @@ export const getEmitNode = (
* @param checkedKeys * @param checkedKeys
* @param checked * @param checked
*/ */
export const patchCheckedKeys = (tree: TreeNode[], checkedKeys: WritableComputedRef<(string | number)[]>, checked = false): void => { export const patchCheckedKeys = (
tree: TreeNode[],
checkedKeys: WritableComputedRef<(string | number)[]>,
checked = false
): void => {
if (!checkedKeys.value) { if (!checkedKeys.value) {
return return
} }
@ -148,7 +152,7 @@ export const patchCheckedKeys = (tree: TreeNode[], checkedKeys: WritableComputed
if (node.children && node.children.length > 0) { if (node.children && node.children.length > 0) {
patchCheckedKeys(node.children, checkedKeys, false) patchCheckedKeys(node.children, checkedKeys, false)
// 判断children是否为都选中如果是都选中的情况下父组件也得是选中 // 判断children是否为都选中如果是都选中的情况下父组件也得是选中
const allChildrenChecked = node.children.every(it => it._checked) const allChildrenChecked = node.children.every((it) => it._checked)
if (allChildrenChecked) { if (allChildrenChecked) {
node._checked = true node._checked = true
} }
@ -172,7 +176,11 @@ function updateChildren(data: TreeNode[], flag: boolean) {
* @param clickNode * @param clickNode
* @param parentNode * @param parentNode
*/ */
export function updateInnerTreeDataChecked(data: TreeNode[], clickNode: TreeNode, parentNode?: TreeNode) { export function updateInnerTreeDataChecked(
data: TreeNode[],
clickNode: TreeNode,
parentNode?: TreeNode
) {
const len = data.length const len = data.length
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
const currentNode = data[i] const currentNode = data[i]
@ -189,7 +197,7 @@ export function updateInnerTreeDataChecked(data: TreeNode[], clickNode: TreeNode
} }
// 当前节点有选中,父节点一定选中 // 当前节点有选中,父节点一定选中
if (currentNode.children && currentNode.children.length > 0) { if (currentNode.children && currentNode.children.length > 0) {
currentNode._checked = currentNode.children.some(it => it._checked) currentNode._checked = currentNode.children.some((it) => it._checked)
} }
} }
} }

View File

@ -3,8 +3,9 @@ import { computed, ref, unref, watch } from 'vue'
import { import {
getCheckedKeys, getCheckedKeys,
getTreeSpreadKeys, getTreeSpreadKeys,
initialTreeData, updateInnerTreeDataChecked initialTreeData,
} from "/@src/module/tree/treeHelper"; updateInnerTreeDataChecked,
} 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) => {
@ -49,10 +50,14 @@ export const useTreeData: UseTreeData = (props, emit) => {
* @param treeData * @param treeData
* @param node * @param node
*/ */
watch(innerTreeData, tree => { watch(
innerTreeData,
(tree) => {
const emitCheckedKeys = getCheckedKeys(tree) const emitCheckedKeys = getCheckedKeys(tree)
checkedKeys.value = emitCheckedKeys checkedKeys.value = emitCheckedKeys
}, { deep: true }) },
{ 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++) {
@ -92,6 +97,6 @@ export const useTreeData: UseTreeData = (props, emit) => {
innerTreeData, innerTreeData,
updateInnerTreeData, updateInnerTreeData,
treeWrapperClass, treeWrapperClass,
updateCheckedByNode updateCheckedByNode,
} }
} }