数通智联化工云平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1 line
12 KiB

2 years ago
{"version":3,"file":"useCheck.mjs","sources":["../../../../../../../packages/components/tree-v2/src/composables/useCheck.ts"],"sourcesContent":["import { getCurrentInstance, nextTick, ref, watch } from 'vue'\nimport {\n NODE_CHECK,\n NODE_CHECK_CHANGE,\n SetOperationEnum,\n} from '../virtual-tree'\nimport type { CheckboxValueType } from '@element-plus/components/checkbox'\nimport type { Ref } from 'vue'\nimport type { Tree, TreeKey, TreeNode, TreeNodeData, TreeProps } from '../types'\n\nexport function useCheck(props: TreeProps, tree: Ref<Tree | undefined>) {\n const checkedKeys = ref<Set<TreeKey>>(new Set())\n const indeterminateKeys = ref<Set<TreeKey>>(new Set())\n const { emit } = getCurrentInstance()!\n\n watch(\n [() => tree.value, () => props.defaultCheckedKeys],\n () => {\n return nextTick(() => {\n _setCheckedKeys(props.defaultCheckedKeys)\n })\n },\n {\n immediate: true,\n }\n )\n\n const updateCheckedKeys = () => {\n if (!tree.value || !props.showCheckbox || props.checkStrictly) {\n return\n }\n const { levelTreeNodeMap, maxLevel } = tree.value\n const checkedKeySet = checkedKeys.value\n const indeterminateKeySet = new Set<TreeKey>()\n // It is easier to determine the indeterminate state by\n // traversing from bottom to top\n // leaf nodes not have indeterminate status and can be skipped\n for (let level = maxLevel - 1; level >= 1; --level) {\n const nodes = levelTreeNodeMap.get(level)\n if (!nodes) continue\n nodes.forEach((node) => {\n const children = node.children\n if (children) {\n // Whether all child nodes are selected\n let allChecked = true\n // Whether a child node is selected\n let hasChecked = false\n for (const childNode of children) {\n const key = childNode.key\n if (checkedKeySet.has(key)) {\n hasChecked = true\n } else if (indeterminateKeySet.has(key)) {\n allChecked = false\n hasChecked = true\n break\n } else {\n allChecked = false\n }\n }\n if (allChecked) {\n checkedKeySet.add(node.key)\n } else if (hasChecked) {\n indeterminateKeySet.add(node.key)\n checkedKeySet.delete(node.key)\n } else {\n checkedKeySet.delete(node.key)\n indeterminateKeySet.delete(node.key)\n }\n }\n })\n }\n indeterminateKeys.value = indeterminateKeySet\n }\n\n const isChecked = (node: TreeNode) => checkedKeys.value.has(node.key)\n\n const isIndeterminate = (node: TreeNode) =>\n indeterminateKeys.value.has(node.key)\n\n const toggleCheckbox = (\n node: TreeNode,\n isChecked: CheckboxValueType,\n nodeClick = true\n ) => {\n const checkedKeySet = checkedKeys.value\n const toggle = (node: TreeNode, checked: CheckboxValueType) => {\n checkedKeySet[checked ? SetOperationEnum.ADD : SetOperationEnum.DELETE](\n node.key\n )\n const children = node.children\n if (!props.checkStrictly && children) {\n children.forEach((childNode) => {\n if (!childNode.disabled) {\n toggle(childNode, checked)\n }\n })\n }\n }\n toggle(node, isChecked)\n updateCheckedKeys()\n if (nodeClick) {\n afterNodeCheck(node, isChecked)\n }\n }\n\n const afterNodeCheck = (node: TreeNode, checked: CheckboxValueType) => {\n const { checkedNodes, checkedKeys } = getChecked()\n const { halfCheckedNodes, halfCheckedKeys } = getHalfChecked()\n emit(NODE_CHECK, node.data, {\n checkedKeys,\n checkedNodes,\n halfCheckedKeys,\n halfCheckedNodes,\n })\n emit(NODE_CHECK_CHANGE, node.data, checked)\n }\n\n // expose\n function getCheckedKeys(leafOnly = false): TreeKey[] {\n return getChecked(leafOnly).checkedKeys\n }\n\n function getCheckedNodes(leafOnly = false): TreeNodeData[] {\n return getChecked(leafOnly).checkedNode