From 3aad5f4aaf78b5e58795bf079665a6e0885097a7 Mon Sep 17 00:00:00 2001 From: WumaCoder <1829913225@qq.com> Date: Sun, 31 Jan 2021 15:28:08 +0800 Subject: [PATCH] refactor(Tree): Based on the implementation of Check-Strictly, is it strictly followed that the father and son are not related to each other in the case of displaying the check box --- .../src/components/Tree/src/TreeMain.vue | 5 ++- .../components/Tree/src/entity/TreeNode.ts | 27 +++++++++++-- .../components/Tree/tests/TreeMain.spec.ts | 35 +++++++++++++++++ .../Tree/tests/entity/TreeNode.spec.ts | 39 +++++++++++++++++++ packages/website/src/play/index.vue | 1 + 5 files changed, 101 insertions(+), 6 deletions(-) diff --git a/packages/element3/src/components/Tree/src/TreeMain.vue b/packages/element3/src/components/Tree/src/TreeMain.vue index f829823ad..d9d177f11 100644 --- a/packages/element3/src/components/Tree/src/TreeMain.vue +++ b/packages/element3/src/components/Tree/src/TreeMain.vue @@ -32,7 +32,8 @@ export default { checked: { type: Array as PropType, default: () => [] }, showCheckbox: Boolean, - checkOnClickNode: Boolean + checkOnClickNode: Boolean, + checkStrictly: Boolean }, emits: ['update:modelValue', 'update:checked'], setup(props, ctx) { @@ -42,6 +43,7 @@ export default { ctx.emit('update:modelValue', tree.rawNodesProxy) const rootChildren = computed(() => tree.root.children) + tree.rootProxy.setStrictly(props.checkStrictly) watchEffect( () => { tree.setCheckedByIds(props.checked) @@ -51,7 +53,6 @@ export default { // exec after wait component flush } ) - watchEffect(() => { ctx.emit('update:checked', tree.getCheckedIds()) }) diff --git a/packages/element3/src/components/Tree/src/entity/TreeNode.ts b/packages/element3/src/components/Tree/src/entity/TreeNode.ts index 0de14b437..bd074dca5 100644 --- a/packages/element3/src/components/Tree/src/entity/TreeNode.ts +++ b/packages/element3/src/components/Tree/src/entity/TreeNode.ts @@ -27,18 +27,30 @@ export class TreeNode implements TreeNodePublicProp { children: TreeNode[] = [] private _isLeaf = false private _isChecked = false + private _isStrictly = false + + get isStrictly(): boolean { + if (this._isStrictly) { + return true + } + + return (this._isStrictly = this.parent?.isStrictly ?? false) + } get isIndeterminate(): boolean { + if (this.isStrictly) { + return false + } const checkedLen = this.getCheckedNodes().length if (this.isLeaf || checkedLen === 0) { return false } - return this.getCheckedNodes().length !== this.children.length + return checkedLen !== this.children.length } get isChecked(): boolean { - if (this.isLeaf) { + if (this.isLeaf || this.isStrictly) { return this._isChecked } @@ -62,11 +74,12 @@ export class TreeNode implements TreeNodePublicProp { id: ID, label: string, children: TreeNode[] = [], - { isLeaf = false, isChecked = false } = {} + { isLeaf = false, isChecked = false, isStrictly = false } = {} ) { this.id = id ?? idSeed++ this.label = label this._isLeaf = isLeaf + this._isStrictly = isStrictly this.setChecked(isChecked) this.appendChild(...children) @@ -74,7 +87,13 @@ export class TreeNode implements TreeNodePublicProp { setChecked(v = !this._isChecked): void { this._isChecked = v - this.children.forEach((node) => node.setChecked(v)) + if (!this.isStrictly) { + this.children.forEach((node) => node.setChecked(v)) + } + } + + setStrictly(v: boolean): void { + this._isStrictly = v } getCheckedNodes(): TreeNode[] { diff --git a/packages/element3/src/components/Tree/tests/TreeMain.spec.ts b/packages/element3/src/components/Tree/tests/TreeMain.spec.ts index eb2bcf69d..a0c99d3fd 100644 --- a/packages/element3/src/components/Tree/tests/TreeMain.spec.ts +++ b/packages/element3/src/components/Tree/tests/TreeMain.spec.ts @@ -202,4 +202,39 @@ describe('TreeMain.vue', () => { await node2.trigger('click') expect(wrapper.vm.checked).toEqual([2]) }) + + it('Implement, in the case of displaying checkboxes, whether to strictly follow the parent-child discordant practice', async () => { + const wrapper = mount({ + template: ` + + `, + components: { elTreeMain: TreeMain }, + setup() { + const nodes = ref([ + { + id: 1, + label: 'Node1', + children: [ + { + id: 2, + label: 'Node2' + } + ] + } + ]) + const checked = ref([]) + return { + nodes, + checked + } + } + }) + + await nextTick() + + const node2 = wrapper.find('#TreeNode2 .el-tree-node__content input') + + await node2.trigger('click') + expect(wrapper.vm.checked).toEqual([2]) + }) }) diff --git a/packages/element3/src/components/Tree/tests/entity/TreeNode.spec.ts b/packages/element3/src/components/Tree/tests/entity/TreeNode.spec.ts index a6ef3dc0c..b61717d92 100644 --- a/packages/element3/src/components/Tree/tests/entity/TreeNode.spec.ts +++ b/packages/element3/src/components/Tree/tests/entity/TreeNode.spec.ts @@ -130,4 +130,43 @@ describe('TreeNode.ts', () => { expect(root.getCheckedNodes()).toHaveLength(2) }) + + it('test isStrictly', () => { + const root = new TreeNode(1, 'Node1', [ + new TreeNode( + 2, + 'Node1-1', + [new TreeNode(3, 'Node1-1-1', [new TreeNode(4, 'Node1-1-1-1')])], + { + isStrictly: true + } + ) + ]) + + expect(root.findOne(4).isStrictly).toBeTruthy() + expect(root.findOne(2).isStrictly).toBeTruthy() + expect(root.isStrictly).toBeFalsy() + }) + + it('test strictly and setChecked', () => { + const root = new TreeNode( + 1, + 'Node1', + [new TreeNode(2, 'Node1-1', [new TreeNode(4, 'Node1-1-1')])], + { + isStrictly: true + } + ) + + root.findOne(2).setChecked(true) + expect(root.findOne(2).isChecked).toBeTruthy() + expect(root.isChecked).toBeFalsy() + expect(root.isIndeterminate).toBeFalsy() + expect(root.findOne(4).isChecked).toBeFalsy() + + root.setChecked(true) + expect(root.isChecked).toBeTruthy() + expect(root.findOne(2).isChecked).toBeTruthy() + expect(root.findOne(4).isChecked).toBeFalsy() + }) }) diff --git a/packages/website/src/play/index.vue b/packages/website/src/play/index.vue index e229b3edf..85ef20463 100644 --- a/packages/website/src/play/index.vue +++ b/packages/website/src/play/index.vue @@ -5,6 +5,7 @@ ref="tree" :show-checkbox="true" :checkOnClickNode="true" + :checkStrictly="true" >