From 7b0fa9428035d6e9f5ca44283ae2e6c87a18ae9e Mon Sep 17 00:00:00 2001 From: ChuChencheng Date: Mon, 1 Jul 2024 01:49:50 +0800 Subject: [PATCH 1/3] doc: use vitepress --- .gitignore | 4 + package.json | 6 +- pnpm-lock.yaml | 492 ++++++++++++++++++ site/.vitepress/code/ActionsSlot.vue | 100 ++++ site/.vitepress/code/BasicDrop.vue | 83 +++ site/.vitepress/code/Cascade.vue | 104 ++++ site/.vitepress/code/Checkable.vue | 86 +++ site/.vitepress/code/CustomDropDisplay.vue | 96 ++++ site/.vitepress/code/CustomDropInput.vue | 92 ++++ site/.vitepress/code/CustomNode.vue | 87 ++++ site/.vitepress/code/DataDisplay.vue | 83 +++ site/.vitepress/code/DragAndDrop.vue | 83 +++ site/.vitepress/code/ExpandAnimation.vue | 83 +++ site/.vitepress/code/IgnoreMode.vue | 108 ++++ site/.vitepress/code/LocalSearch.vue | 85 +++ .../code/NodeCreationAndRemoval.vue | 121 +++++ site/.vitepress/code/Performance.vue | 219 ++++++++ site/.vitepress/code/Remote.vue | 27 + site/.vitepress/code/RemoteSearch.vue | 38 ++ site/.vitepress/code/Selectable.vue | 86 +++ .../code/SelectableAndCheckable.vue | 86 +++ site/.vitepress/code/ShowLine.vue | 114 ++++ site/.vitepress/components/Playground.vue | 32 ++ site/.vitepress/components/PlaygroundLink.vue | 50 ++ site/.vitepress/components/code-demo.md | 37 ++ site/.vitepress/config.mts | 30 ++ site/.vitepress/constants/i18n.ts | 43 ++ site/.vitepress/data/code.data.ts | 25 + site/.vitepress/en.mts | 9 + site/.vitepress/theme/index.ts | 26 + site/.vitepress/utils/i18n.ts | 42 ++ site/.vitepress/zh.mts | 9 + site/api/vtree-drop.md | 61 +++ site/api/vtree-search.md | 47 ++ site/api/vtree.md | 130 +++++ site/en/api/vtree-drop.md | 61 +++ site/en/api/vtree-search.md | 47 ++ site/en/api/vtree.md | 130 +++++ site/en/examples/node-manipulation.md | 24 + site/en/examples/performance.md | 7 + site/en/examples/tree-drop.md | 19 + site/en/examples/tree-search.md | 19 + site/en/examples/tree.md | 58 +++ site/en/guide/getting-started.md | 38 ++ site/en/guide/migration.md | 23 + site/en/index.md | 28 + site/examples/node-manipulation.md | 24 + site/examples/performance.md | 7 + site/examples/tree-drop.md | 19 + site/examples/tree-search.md | 19 + site/examples/tree.md | 58 +++ site/guide/getting-started.md | 38 ++ site/guide/migration.md | 23 + site/index.md | 28 + site/package.json | 9 + site/playground.md | 11 + site/pnpm-lock.yaml | 23 + 57 files changed, 3536 insertions(+), 1 deletion(-) create mode 100644 site/.vitepress/code/ActionsSlot.vue create mode 100644 site/.vitepress/code/BasicDrop.vue create mode 100644 site/.vitepress/code/Cascade.vue create mode 100644 site/.vitepress/code/Checkable.vue create mode 100644 site/.vitepress/code/CustomDropDisplay.vue create mode 100644 site/.vitepress/code/CustomDropInput.vue create mode 100644 site/.vitepress/code/CustomNode.vue create mode 100644 site/.vitepress/code/DataDisplay.vue create mode 100644 site/.vitepress/code/DragAndDrop.vue create mode 100644 site/.vitepress/code/ExpandAnimation.vue create mode 100644 site/.vitepress/code/IgnoreMode.vue create mode 100644 site/.vitepress/code/LocalSearch.vue create mode 100644 site/.vitepress/code/NodeCreationAndRemoval.vue create mode 100644 site/.vitepress/code/Performance.vue create mode 100644 site/.vitepress/code/Remote.vue create mode 100644 site/.vitepress/code/RemoteSearch.vue create mode 100644 site/.vitepress/code/Selectable.vue create mode 100644 site/.vitepress/code/SelectableAndCheckable.vue create mode 100644 site/.vitepress/code/ShowLine.vue create mode 100644 site/.vitepress/components/Playground.vue create mode 100644 site/.vitepress/components/PlaygroundLink.vue create mode 100644 site/.vitepress/components/code-demo.md create mode 100644 site/.vitepress/config.mts create mode 100644 site/.vitepress/constants/i18n.ts create mode 100644 site/.vitepress/data/code.data.ts create mode 100644 site/.vitepress/en.mts create mode 100644 site/.vitepress/theme/index.ts create mode 100644 site/.vitepress/utils/i18n.ts create mode 100644 site/.vitepress/zh.mts create mode 100644 site/api/vtree-drop.md create mode 100644 site/api/vtree-search.md create mode 100644 site/api/vtree.md create mode 100644 site/en/api/vtree-drop.md create mode 100644 site/en/api/vtree-search.md create mode 100644 site/en/api/vtree.md create mode 100644 site/en/examples/node-manipulation.md create mode 100644 site/en/examples/performance.md create mode 100644 site/en/examples/tree-drop.md create mode 100644 site/en/examples/tree-search.md create mode 100644 site/en/examples/tree.md create mode 100644 site/en/guide/getting-started.md create mode 100644 site/en/guide/migration.md create mode 100644 site/en/index.md create mode 100644 site/examples/node-manipulation.md create mode 100644 site/examples/performance.md create mode 100644 site/examples/tree-drop.md create mode 100644 site/examples/tree-search.md create mode 100644 site/examples/tree.md create mode 100644 site/guide/getting-started.md create mode 100644 site/guide/migration.md create mode 100644 site/index.md create mode 100644 site/package.json create mode 100644 site/playground.md create mode 100644 site/pnpm-lock.yaml diff --git a/.gitignore b/.gitignore index 2e37eda..a976bba 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ yarn-error.log* *.njsproj *.sln *.sw* + +# Vitepress +site/.vitepress/dist +site/.vitepress/cache diff --git a/package.json b/package.json index a4e9840..7ce4241 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,10 @@ "test": "vitest watch", "test:ci": "vitest run", "prettier": "prettier --write \"{src,examples,tests}/**/*.{ts,js,json,vue,tsx,less,scss,less,html}\" --fix", - "prepublishOnly": "npm run build" + "prepublishOnly": "npm run build", + "docs:dev": "vitepress dev site", + "docs:build": "vitepress build site", + "docs:preview": "vitepress preview site" }, "publishConfig": { "registry": "https://registry.npmjs.org/", @@ -70,6 +73,7 @@ "prettier": "^3.3.1", "typescript": "^5.4.5", "vite": "^5.2.13", + "vitepress": "^1.2.3", "vitest": "^1.6.0", "vue": "^3.4.30", "vue-tsc": "^2.0.22" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ac29ab..15b512e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ devDependencies: vite: specifier: ^5.2.13 version: 5.2.13(less@4.2.0) + vitepress: + specifier: ^1.2.3 + version: 1.2.3(@algolia/client-search@4.24.0)(less@4.2.0)(postcss@8.4.38)(search-insights@2.14.0)(typescript@5.4.5) vitest: specifier: ^1.6.0 version: 1.6.0(happy-dom@14.12.0)(less@4.2.0) @@ -59,6 +62,156 @@ devDependencies: packages: + /@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.14.0): + resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.14.0) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + dev: true + + /@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.14.0): + resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} + peerDependencies: + search-insights: '>= 1 < 3' + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + search-insights: 2.14.0 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + dev: true + + /@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0): + resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + '@algolia/client-search': 4.24.0 + algoliasearch: 4.24.0 + dev: true + + /@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0): + resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + dependencies: + '@algolia/client-search': 4.24.0 + algoliasearch: 4.24.0 + dev: true + + /@algolia/cache-browser-local-storage@4.24.0: + resolution: {integrity: sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==} + dependencies: + '@algolia/cache-common': 4.24.0 + dev: true + + /@algolia/cache-common@4.24.0: + resolution: {integrity: sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==} + dev: true + + /@algolia/cache-in-memory@4.24.0: + resolution: {integrity: sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==} + dependencies: + '@algolia/cache-common': 4.24.0 + dev: true + + /@algolia/client-account@4.24.0: + resolution: {integrity: sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==} + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/transporter': 4.24.0 + dev: true + + /@algolia/client-analytics@4.24.0: + resolution: {integrity: sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==} + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + dev: true + + /@algolia/client-common@4.24.0: + resolution: {integrity: sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==} + dependencies: + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + dev: true + + /@algolia/client-personalization@4.24.0: + resolution: {integrity: sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==} + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + dev: true + + /@algolia/client-search@4.24.0: + resolution: {integrity: sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==} + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + dev: true + + /@algolia/logger-common@4.24.0: + resolution: {integrity: sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==} + dev: true + + /@algolia/logger-console@4.24.0: + resolution: {integrity: sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==} + dependencies: + '@algolia/logger-common': 4.24.0 + dev: true + + /@algolia/recommend@4.24.0: + resolution: {integrity: sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==} + dependencies: + '@algolia/cache-browser-local-storage': 4.24.0 + '@algolia/cache-common': 4.24.0 + '@algolia/cache-in-memory': 4.24.0 + '@algolia/client-common': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/logger-common': 4.24.0 + '@algolia/logger-console': 4.24.0 + '@algolia/requester-browser-xhr': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/requester-node-http': 4.24.0 + '@algolia/transporter': 4.24.0 + dev: true + + /@algolia/requester-browser-xhr@4.24.0: + resolution: {integrity: sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==} + dependencies: + '@algolia/requester-common': 4.24.0 + dev: true + + /@algolia/requester-common@4.24.0: + resolution: {integrity: sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==} + dev: true + + /@algolia/requester-node-http@4.24.0: + resolution: {integrity: sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==} + dependencies: + '@algolia/requester-common': 4.24.0 + dev: true + + /@algolia/transporter@4.24.0: + resolution: {integrity: sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==} + dependencies: + '@algolia/cache-common': 4.24.0 + '@algolia/logger-common': 4.24.0 + '@algolia/requester-common': 4.24.0 + dev: true + /@ampproject/remapping@2.3.0: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -1429,6 +1582,49 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true + /@docsearch/css@3.6.0: + resolution: {integrity: sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==} + dev: true + + /@docsearch/js@3.6.0(@algolia/client-search@4.24.0)(search-insights@2.14.0): + resolution: {integrity: sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ==} + dependencies: + '@docsearch/react': 3.6.0(@algolia/client-search@4.24.0)(search-insights@2.14.0) + preact: 10.22.0 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + dev: true + + /@docsearch/react@3.6.0(@algolia/client-search@4.24.0)(search-insights@2.14.0): + resolution: {integrity: sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + dependencies: + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.14.0) + '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + '@docsearch/css': 3.6.0 + algoliasearch: 4.24.0 + search-insights: 2.14.0 + transitivePeerDependencies: + - '@algolia/client-search' + dev: true + /@esbuild/aix-ppc64@0.20.2: resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} engines: {node: '>=12'} @@ -2052,6 +2248,16 @@ packages: dev: true optional: true + /@shikijs/core@1.9.1: + resolution: {integrity: sha512-EmUful2MQtY8KgCF1OkBtOuMcvaZEvmdubhW0UHCGXi21O9dRLeADVCj+k6ZS+de7Mz9d2qixOXJ+GLhcK3pXg==} + dev: true + + /@shikijs/transformers@1.9.1: + resolution: {integrity: sha512-wPrGTpBURQ95IKPIhPQE3bGsANpPPtea1+aVHZp0aYtgxfL5UM3QbJ5rNdCuhcyjz/JNp5ZvSItOr+ayJxebJQ==} + dependencies: + shiki: 1.9.1 + dev: true + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true @@ -2123,6 +2329,21 @@ packages: '@types/istanbul-lib-report': 3.0.3 dev: true + /@types/linkify-it@5.0.0: + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + dev: true + + /@types/markdown-it@14.1.1: + resolution: {integrity: sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg==} + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + dev: true + + /@types/mdurl@2.0.0: + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + dev: true + /@types/node@20.14.8: resolution: {integrity: sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==} dependencies: @@ -2141,6 +2362,10 @@ packages: resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} dev: true + /@types/web-bluetooth@0.0.20: + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + dev: true + /@types/yargs-parser@21.0.3: resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} dev: true @@ -2438,6 +2663,30 @@ packages: '@vue/shared': 3.4.30 dev: true + /@vue/devtools-api@7.3.4: + resolution: {integrity: sha512-E5dJlLW+NgGb+WS33y99ioOJL2OXpVhje6VwXGJ/q5fNizJDpe67Ml0GBSrlYOKNSjZs2mwcZd7B3e12th3Q0g==} + dependencies: + '@vue/devtools-kit': 7.3.4 + dev: true + + /@vue/devtools-kit@7.3.4: + resolution: {integrity: sha512-DalQZWaFLRyA4qfKT0WT7e+q2AwvYoTwd0pWqswHqcpviXw+oU6FlSJHMrEACB3lBHjN1KBS9Kh527sWIe1vcg==} + dependencies: + '@vue/devtools-shared': 7.3.4 + birpc: 0.2.17 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.1 + dev: true + + /@vue/devtools-shared@7.3.4: + resolution: {integrity: sha512-5S5cHh7oWLZdboujnLteR3rT8UGfKHfA34aGLyFRB/B5TqBxmeLW1Rq32xW6TCDEy4isoYsYHGwJVp6DQcpiDA==} + dependencies: + rfdc: 1.4.1 + dev: true + /@vue/language-core@2.0.22(typescript@5.4.5): resolution: {integrity: sha512-dNTAAtEOuMiz7N1s5tKpypnVVCtawxVSF5BukD0ELcYSw+DSbrSlYYSw8GuwvurodCeYFSHsmslE+c2sYDNoiA==} peerDependencies: @@ -2528,6 +2777,81 @@ packages: - supports-color dev: true + /@vueuse/core@10.11.0(vue@3.4.30): + resolution: {integrity: sha512-x3sD4Mkm7PJ+pcq3HX8PLPBadXCAlSDR/waK87dz0gQE+qJnaaFhc/dZVfJz+IUYzTMVGum2QlR7ImiJQN4s6g==} + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.11.0 + '@vueuse/shared': 10.11.0(vue@3.4.30) + vue-demi: 0.14.8(vue@3.4.30) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /@vueuse/integrations@10.11.0(focus-trap@7.5.4)(vue@3.4.30): + resolution: {integrity: sha512-Pp6MtWEIr+NDOccWd8j59Kpjy5YDXogXI61Kb1JxvSfVBO8NzFQkmrKmSZz47i+ZqHnIzxaT38L358yDHTncZg==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^4 + drauu: ^0.3 + focus-trap: ^7 + fuse.js: ^6 + idb-keyval: ^6 + jwt-decode: ^3 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^6 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + dependencies: + '@vueuse/core': 10.11.0(vue@3.4.30) + '@vueuse/shared': 10.11.0(vue@3.4.30) + focus-trap: 7.5.4 + vue-demi: 0.14.8(vue@3.4.30) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /@vueuse/metadata@10.11.0: + resolution: {integrity: sha512-kQX7l6l8dVWNqlqyN3ePW3KmjCQO3ZMgXuBMddIu83CmucrsBfXlH+JoviYyRBws/yLTQO8g3Pbw+bdIoVm4oQ==} + dev: true + + /@vueuse/shared@10.11.0(vue@3.4.30): + resolution: {integrity: sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==} + dependencies: + vue-demi: 0.14.8(vue@3.4.30) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + /abbrev@2.0.0: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -2546,6 +2870,26 @@ packages: hasBin: true dev: true + /algoliasearch@4.24.0: + resolution: {integrity: sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==} + dependencies: + '@algolia/cache-browser-local-storage': 4.24.0 + '@algolia/cache-common': 4.24.0 + '@algolia/cache-in-memory': 4.24.0 + '@algolia/client-account': 4.24.0 + '@algolia/client-analytics': 4.24.0 + '@algolia/client-common': 4.24.0 + '@algolia/client-personalization': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/logger-common': 4.24.0 + '@algolia/logger-console': 4.24.0 + '@algolia/recommend': 4.24.0 + '@algolia/requester-browser-xhr': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/requester-node-http': 4.24.0 + '@algolia/transporter': 4.24.0 + dev: true + /ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -2739,6 +3083,10 @@ packages: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true + /birpc@0.2.17: + resolution: {integrity: sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==} + dev: true + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -2942,6 +3290,13 @@ packages: is-what: 3.14.1 dev: true + /copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + dependencies: + is-what: 4.1.16 + dev: true + /core-js-compat@3.37.1: resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==} dependencies: @@ -3255,6 +3610,12 @@ packages: path-exists: 4.0.0 dev: true + /focus-trap@7.5.4: + resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} + dependencies: + tabbable: 6.2.0 + dev: true + /foreground-child@3.2.1: resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} engines: {node: '>=14'} @@ -3410,6 +3771,10 @@ packages: hasBin: true dev: true + /hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + dev: true + /html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true @@ -3520,6 +3885,11 @@ packages: resolution: {integrity: sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==} dev: true + /is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + dev: true + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -4157,6 +4527,10 @@ packages: tmpl: 1.0.5 dev: true + /mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + dev: true + /mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} dev: true @@ -4216,6 +4590,14 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dev: true + /minisearch@6.3.0: + resolution: {integrity: sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==} + dev: true + + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + dev: true + /mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} dependencies: @@ -4425,6 +4807,10 @@ packages: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true + /perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + dev: true + /picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} dev: true @@ -4473,6 +4859,10 @@ packages: source-map-js: 1.2.0 dev: true + /preact@10.22.0: + resolution: {integrity: sha512-RRurnSjJPj4rp5K6XoP45Ui33ncb7e4H7WiOHVpjbkvqvA3U+N8Z6Qbo0AE6leGYBV66n8EhEaFixvIu3SkxFw==} + dev: true + /prettier@3.3.1: resolution: {integrity: sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==} engines: {node: '>=14'} @@ -4584,6 +4974,10 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true + /rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + dev: true + /rollup@4.18.0: resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -4620,6 +5014,10 @@ packages: dev: true optional: true + /search-insights@2.14.0: + resolution: {integrity: sha512-OLN6MsPMCghDOqlCtsIsYgtsC0pnwVTyT9Mu6A3ewOj1DxvzZF6COrn2g86E/c05xbktB0XN04m/t1Z+n+fTGw==} + dev: true + /semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -4661,6 +5059,12 @@ packages: engines: {node: '>=8'} dev: true + /shiki@1.9.1: + resolution: {integrity: sha512-8PDkgb5ja3nfujTjvC4VytL6wGOGCtFAClUb2r3QROevYXxcq+/shVJK5s6gy0HZnjaJgFxd6BpPqpRfqne5rA==} + dependencies: + '@shikijs/core': 1.9.1 + dev: true + /siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} dev: true @@ -4705,6 +5109,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + dev: true + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true @@ -4800,6 +5209,13 @@ packages: js-tokens: 9.0.0 dev: true + /superjson@2.2.1: + resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} + engines: {node: '>=16'} + dependencies: + copy-anything: 3.0.5 + dev: true + /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -4830,6 +5246,10 @@ packages: resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} dev: true + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + dev: true + /test-exclude@6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -5006,6 +5426,63 @@ packages: fsevents: 2.3.3 dev: true + /vitepress@1.2.3(@algolia/client-search@4.24.0)(less@4.2.0)(postcss@8.4.38)(search-insights@2.14.0)(typescript@5.4.5): + resolution: {integrity: sha512-GvEsrEeNLiDE1+fuwDAYJCYLNZDAna+EtnXlPajhv/MYeTjbNK6Bvyg6NoTdO1sbwuQJ0vuJR99bOlH53bo6lg==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + dependencies: + '@docsearch/css': 3.6.0 + '@docsearch/js': 3.6.0(@algolia/client-search@4.24.0)(search-insights@2.14.0) + '@shikijs/core': 1.9.1 + '@shikijs/transformers': 1.9.1 + '@types/markdown-it': 14.1.1 + '@vitejs/plugin-vue': 5.0.5(vite@5.2.13)(vue@3.4.30) + '@vue/devtools-api': 7.3.4 + '@vue/shared': 3.4.30 + '@vueuse/core': 10.11.0(vue@3.4.30) + '@vueuse/integrations': 10.11.0(focus-trap@7.5.4)(vue@3.4.30) + focus-trap: 7.5.4 + mark.js: 8.11.1 + minisearch: 6.3.0 + postcss: 8.4.38 + shiki: 1.9.1 + vite: 5.2.13(less@4.2.0) + vue: 3.4.30(typescript@5.4.5) + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - react + - react-dom + - sass + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - typescript + - universal-cookie + dev: true + /vitest@1.6.0(happy-dom@14.12.0)(less@4.2.0): resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -5070,6 +5547,21 @@ packages: resolution: {integrity: sha512-gPr2Ba7efUwy/Vfbuf735bHSVdN4ycoZUCHfypkI33M9DUH+ieRblLLVM2eImccFYaWNWwEzURx02EgoXDBmaQ==} dev: true + /vue-demi@0.14.8(vue@3.4.30): + resolution: {integrity: sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + dependencies: + vue: 3.4.30(typescript@5.4.5) + dev: true + /vue-template-compiler@2.7.16: resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} dependencies: diff --git a/site/.vitepress/code/ActionsSlot.vue b/site/.vitepress/code/ActionsSlot.vue new file mode 100644 index 0000000..0868861 --- /dev/null +++ b/site/.vitepress/code/ActionsSlot.vue @@ -0,0 +1,100 @@ + + + diff --git a/site/.vitepress/code/BasicDrop.vue b/site/.vitepress/code/BasicDrop.vue new file mode 100644 index 0000000..9a4696f --- /dev/null +++ b/site/.vitepress/code/BasicDrop.vue @@ -0,0 +1,83 @@ + + + diff --git a/site/.vitepress/code/Cascade.vue b/site/.vitepress/code/Cascade.vue new file mode 100644 index 0000000..718d993 --- /dev/null +++ b/site/.vitepress/code/Cascade.vue @@ -0,0 +1,104 @@ + + + diff --git a/site/.vitepress/code/Checkable.vue b/site/.vitepress/code/Checkable.vue new file mode 100644 index 0000000..280f2c6 --- /dev/null +++ b/site/.vitepress/code/Checkable.vue @@ -0,0 +1,86 @@ + + + diff --git a/site/.vitepress/code/CustomDropDisplay.vue b/site/.vitepress/code/CustomDropDisplay.vue new file mode 100644 index 0000000..73f9e3e --- /dev/null +++ b/site/.vitepress/code/CustomDropDisplay.vue @@ -0,0 +1,96 @@ + + + diff --git a/site/.vitepress/code/CustomDropInput.vue b/site/.vitepress/code/CustomDropInput.vue new file mode 100644 index 0000000..b3e6dbf --- /dev/null +++ b/site/.vitepress/code/CustomDropInput.vue @@ -0,0 +1,92 @@ + + + diff --git a/site/.vitepress/code/CustomNode.vue b/site/.vitepress/code/CustomNode.vue new file mode 100644 index 0000000..41dac41 --- /dev/null +++ b/site/.vitepress/code/CustomNode.vue @@ -0,0 +1,87 @@ + + + diff --git a/site/.vitepress/code/DataDisplay.vue b/site/.vitepress/code/DataDisplay.vue new file mode 100644 index 0000000..422e67a --- /dev/null +++ b/site/.vitepress/code/DataDisplay.vue @@ -0,0 +1,83 @@ + + + diff --git a/site/.vitepress/code/DragAndDrop.vue b/site/.vitepress/code/DragAndDrop.vue new file mode 100644 index 0000000..a980c1d --- /dev/null +++ b/site/.vitepress/code/DragAndDrop.vue @@ -0,0 +1,83 @@ + + + diff --git a/site/.vitepress/code/ExpandAnimation.vue b/site/.vitepress/code/ExpandAnimation.vue new file mode 100644 index 0000000..4822701 --- /dev/null +++ b/site/.vitepress/code/ExpandAnimation.vue @@ -0,0 +1,83 @@ + + + diff --git a/site/.vitepress/code/IgnoreMode.vue b/site/.vitepress/code/IgnoreMode.vue new file mode 100644 index 0000000..bd11bc6 --- /dev/null +++ b/site/.vitepress/code/IgnoreMode.vue @@ -0,0 +1,108 @@ + + + diff --git a/site/.vitepress/code/LocalSearch.vue b/site/.vitepress/code/LocalSearch.vue new file mode 100644 index 0000000..fd36896 --- /dev/null +++ b/site/.vitepress/code/LocalSearch.vue @@ -0,0 +1,85 @@ + + + diff --git a/site/.vitepress/code/NodeCreationAndRemoval.vue b/site/.vitepress/code/NodeCreationAndRemoval.vue new file mode 100644 index 0000000..e836d85 --- /dev/null +++ b/site/.vitepress/code/NodeCreationAndRemoval.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/site/.vitepress/code/Performance.vue b/site/.vitepress/code/Performance.vue new file mode 100644 index 0000000..9c164a7 --- /dev/null +++ b/site/.vitepress/code/Performance.vue @@ -0,0 +1,219 @@ + + + + + + + diff --git a/site/.vitepress/code/Remote.vue b/site/.vitepress/code/Remote.vue new file mode 100644 index 0000000..c61d8b8 --- /dev/null +++ b/site/.vitepress/code/Remote.vue @@ -0,0 +1,27 @@ + + + diff --git a/site/.vitepress/code/RemoteSearch.vue b/site/.vitepress/code/RemoteSearch.vue new file mode 100644 index 0000000..78e5308 --- /dev/null +++ b/site/.vitepress/code/RemoteSearch.vue @@ -0,0 +1,38 @@ + + + diff --git a/site/.vitepress/code/Selectable.vue b/site/.vitepress/code/Selectable.vue new file mode 100644 index 0000000..002b297 --- /dev/null +++ b/site/.vitepress/code/Selectable.vue @@ -0,0 +1,86 @@ + + + diff --git a/site/.vitepress/code/SelectableAndCheckable.vue b/site/.vitepress/code/SelectableAndCheckable.vue new file mode 100644 index 0000000..d1a7454 --- /dev/null +++ b/site/.vitepress/code/SelectableAndCheckable.vue @@ -0,0 +1,86 @@ + + + diff --git a/site/.vitepress/code/ShowLine.vue b/site/.vitepress/code/ShowLine.vue new file mode 100644 index 0000000..d2af7d0 --- /dev/null +++ b/site/.vitepress/code/ShowLine.vue @@ -0,0 +1,114 @@ + + + diff --git a/site/.vitepress/components/Playground.vue b/site/.vitepress/components/Playground.vue new file mode 100644 index 0000000..52c0ff7 --- /dev/null +++ b/site/.vitepress/components/Playground.vue @@ -0,0 +1,32 @@ + + + + + diff --git a/site/.vitepress/components/PlaygroundLink.vue b/site/.vitepress/components/PlaygroundLink.vue new file mode 100644 index 0000000..5adda08 --- /dev/null +++ b/site/.vitepress/components/PlaygroundLink.vue @@ -0,0 +1,50 @@ + + + diff --git a/site/.vitepress/components/code-demo.md b/site/.vitepress/components/code-demo.md new file mode 100644 index 0000000..409d4cb --- /dev/null +++ b/site/.vitepress/components/code-demo.md @@ -0,0 +1,37 @@ +
+ +
+ +

+ +

+ +::: details {{i18n.showCode}} +
+::: + + diff --git a/site/.vitepress/config.mts b/site/.vitepress/config.mts new file mode 100644 index 0000000..1c8262f --- /dev/null +++ b/site/.vitepress/config.mts @@ -0,0 +1,30 @@ +import { defineConfig } from 'vitepress' +import zh from './zh.mjs' +import en from './en.mjs' + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: "Vue Tree", + description: "Virtual list optimized Vue tree component", + appearance: false, + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + search: { + provider: 'local' + }, + socialLinks: [ + { icon: 'github', link: 'https://github.com/wsfe/vue-tree' } + ] + }, + + locales: { + root: { + label: '简体中文', + ...zh, + }, + en: { + label: 'English', + ...en, + }, + }, +}) diff --git a/site/.vitepress/constants/i18n.ts b/site/.vitepress/constants/i18n.ts new file mode 100644 index 0000000..dafcd50 --- /dev/null +++ b/site/.vitepress/constants/i18n.ts @@ -0,0 +1,43 @@ +export const codeDemoI18n = { + root: { + showCode: '查看代码', + openInPlayground: '在 Playground 打开示例', + }, + en: { + showCode: 'Show code', + openInPlayground: 'Open example in Playground', + }, +} + +const themeConfigI18n = { + zh: { + guide: '指南', + examples: '示例', + api: '接口文档', + + gettingStarted: '快速开始', + migration: '从旧版迁移', + basicUsage: '基本用法', + performance: '性能测试', + nodeManipulation: '节点操作', + treeSearch: '树搜索', + treeDrop: '树下拉', + }, + en: { + guide: 'Guide', + examples: 'Examples', + api: 'API Document', + + gettingStarted: 'Getting Started', + migration: 'Migrate from Old Version', + basicUsage: 'Basic Usage', + performance: 'Performance', + nodeManipulation: 'Node Manipulation', + treeSearch: 'Tree Search', + treeDrop: 'Tree Drop', + }, +} + +;(themeConfigI18n as any).root = themeConfigI18n.zh + +export { themeConfigI18n } diff --git a/site/.vitepress/data/code.data.ts b/site/.vitepress/data/code.data.ts new file mode 100644 index 0000000..13b7da4 --- /dev/null +++ b/site/.vitepress/data/code.data.ts @@ -0,0 +1,25 @@ +import fs from 'node:fs/promises' +import path from 'node:path' +import { createMarkdownRenderer } from 'vitepress' + +export default { + async load() { + const md = await createMarkdownRenderer('') + + const codeDirName = path.resolve(__dirname, '../code') + const fileNameList = await fs.readdir(codeDirName) + const sourceCodeMap: Record = {} + for (let fileName of fileNameList) { + const [, componentName, extension] = fileName.match(/^(.+?)?(?:\.(.+))?$/) || [] + if (componentName) { + const sourceCode = (await fs.readFile(path.resolve(codeDirName, fileName), { encoding: 'utf8' })).toString() + sourceCodeMap[componentName] = { + markdown: md.render(`\`\`\`${extension || 'vue'}\n${sourceCode}\n\`\`\``), + sourceCode, + extension, + } + } + } + return sourceCodeMap + } +} diff --git a/site/.vitepress/en.mts b/site/.vitepress/en.mts new file mode 100644 index 0000000..f88044b --- /dev/null +++ b/site/.vitepress/en.mts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vitepress' +import { getLocaleThemeConfig } from './utils/i18n' + +const lang = 'en' + +export default defineConfig({ + lang, + themeConfig: getLocaleThemeConfig(lang), +}) diff --git a/site/.vitepress/theme/index.ts b/site/.vitepress/theme/index.ts new file mode 100644 index 0000000..cec9887 --- /dev/null +++ b/site/.vitepress/theme/index.ts @@ -0,0 +1,26 @@ +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' + +import CodeDemo from '../components/code-demo.md' +import PlaygroundLink from '../components/PlaygroundLink.vue' +import '@wsfe/vue-tree/style.css' + +const codeDemoComponents = import.meta.glob('../code/*.vue') + +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + // 注册自定义全局组件 + app.component('CodeDemo', CodeDemo) + app.component('PlaygroundLink', PlaygroundLink) + + for (const path in codeDemoComponents) { + codeDemoComponents[path]().then((component) => { + const componentName = path.match(/^(?:.*\/)?(.+)\.vue$/)?.[1] + if (componentName && component?.default) { + app.component(componentName, component.default) + } + }) + } + } +} satisfies Theme diff --git a/site/.vitepress/utils/i18n.ts b/site/.vitepress/utils/i18n.ts new file mode 100644 index 0000000..adac765 --- /dev/null +++ b/site/.vitepress/utils/i18n.ts @@ -0,0 +1,42 @@ +import { themeConfigI18n } from "../constants/i18n" + +export const getLocaleThemeConfig = (lang: string) => { + const pathPrefix = lang === 'root' || lang === 'zh' ? '' : `/${lang}` + const i18nMap = themeConfigI18n[lang] + + return { + nav: [ + { text: i18nMap.guide, link: `${pathPrefix}/guide/getting-started`, activeMatch: '/guide' }, + { text: i18nMap.examples, link: `${pathPrefix}/examples/tree`, activeMatch: '/examples' }, + { text: i18nMap.api, link: `${pathPrefix}/api/vtree`, activeMatch: '/api' }, + ], + + sidebar: [ + { + text: i18nMap.guide, + items: [ + { text: i18nMap.gettingStarted, link: `${pathPrefix}/guide/getting-started` }, + { text: i18nMap.migration, link: `${pathPrefix}/guide/migration` }, + ] + }, + { + text: i18nMap.examples, + items: [ + { text: i18nMap.basicUsage, link: `${pathPrefix}/examples/tree` }, + { text: i18nMap.performance, link: `${pathPrefix}/examples/performance` }, + { text: i18nMap.nodeManipulation, link: `${pathPrefix}/examples/node-manipulation` }, + { text: i18nMap.treeSearch, link: `${pathPrefix}/examples/tree-search` }, + { text: i18nMap.treeDrop, link: `${pathPrefix}/examples/tree-drop` }, + ] + }, + { + text: i18nMap.api, + items: [ + { text: 'VTree', link: `${pathPrefix}/api/vtree` }, + { text: 'VTreeSearch', link: `${pathPrefix}/api/vtree-search` }, + { text: 'VTreeDrop', link: `${pathPrefix}/api/vtree-drop` }, + ] + }, + ], + } +} diff --git a/site/.vitepress/zh.mts b/site/.vitepress/zh.mts new file mode 100644 index 0000000..a6d1974 --- /dev/null +++ b/site/.vitepress/zh.mts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vitepress' +import { getLocaleThemeConfig } from './utils/i18n' + +const lang = 'zh' + +export default defineConfig({ + lang, + themeConfig: getLocaleThemeConfig(lang), +}) diff --git a/site/api/vtree-drop.md b/site/api/vtree-drop.md new file mode 100644 index 0000000..e7ce6d5 --- /dev/null +++ b/site/api/vtree-drop.md @@ -0,0 +1,61 @@ +# VTreeDrop API + +## VTreeDrop Props + +注:可在 `VTreeDrop` 上直接使用 `VTree` 和 `VTreeSearch` 的所有 Props + +| 属性 | 说明 | 类型 | 默认值 | +| :------------------------- | :------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- | :------------- | +| dropHeight | 下拉内容高度 | `number` | 300 | +| dropPlaceholder | 展示输入框 placeholder | `string` | 无 | +| dropDisabled | 是否禁用 | `boolean` | false | +| clearable | 允许清空 | `boolean` | false | +| placement | 下拉弹出框位置,注意!!不支持自动识别方向 | `'bottom-start' \| 'bottom-end' \| 'bottom' \| 'top-start' \| 'top-end' \| 'top'` | 'bottom-start' | +| transfer | 将下拉 DOM 转移到 body 中 | `boolean` | false | +| dropdownClassName | 在下拉框容器上额外添加的 class | `string \| string[]` | 无 | +| dropdownMinWidth `2.0.1` | 下拉框容器最小宽度,未指定则默认为展示输入框宽度。 适合 transfer 为 false 时使用 | `number` | 无 | +| dropdownWidthFixed `2.0.5` | 固定下拉框容器宽度,当内容超出最小宽度不会伸长,而是出现横向滚动条 | `boolean` | false | + +## VTreeDrop Events + +注:可在 `VTreeDrop` 上直接监听 `VTree` 和 `VTreeSearch` 的所有 Events + +| 事件名 | 说明 | 返回值 | +| :---------------------- | :--------------------- | :------------- | +| dropdown-visible-change | 下拉框出现或消失时触发 | 下拉框是否可见 | +| clear | 点击清空按钮时触发 | 无 | + +## VTreeDrop Methods + +注:可在 `VTreeDrop` 上直接调用 `VTree` 和 `VTreeSearch` 的所有 Methods + +## VTreeDrop Slots + +注:可在 `VTreeDrop` 上直接传入 `VTree` 和 `VTreeSearch` 的所有 Slots + +| 名称 | 说明 | +| :------ | :--------------------------------------------------- | +| 默认 | 展示输入框 | +| display | 展示输入框的展示文字,如果有默认 slot 则此 slot 无效 | +| clear | 替换清空图标,如果有默认 slot 则此 slot 无效 | + +默认 slot 与 display slot 的 Slot Props `2.3.0` : + +```typescript +/** 展示 slot 的 props */ +slotProps: { + /** 多选选中的节点 */ + checkedNodes: [] as TreeNode[], + + /** 多选选中的节点 key */ + checkedKeys: [] as Array, + + /** 单选选中的节点 */ + selectedNode: null as TreeNode | null, + + /** 单选选中的节点 key */ + selectedKey: null as string | number | null, +}, +``` + +**注意**: `checkedNodes` 与 `selectedNode` 只包含已加载的节点,如果设置了选中的值(比如设置了 `value` Prop),但没有设置树的数据,则这两个字段内容将为空;而 `checkedKeys` 与 `selectedKey` 则会包含未加载的选中节点 key 。 diff --git a/site/api/vtree-search.md b/site/api/vtree-search.md new file mode 100644 index 0000000..54a4909 --- /dev/null +++ b/site/api/vtree-search.md @@ -0,0 +1,47 @@ +# VTreeSearch API + +## VTreeSearch Props + +注:可在 `VTreeSearch` 上直接使用 `VTree` 的所有 Props + +| 属性 | 说明 | 类型 | 默认值 | +| :------------------- | :--------------------------------------------------------------------------------- | :------------------------------------------- | :----------- | +| searchPlaceholder | 搜索输入框的 placeholder | `string` | '搜索关键字' | +| showCheckAll | 是否显示全选复选框 | `boolean` | true | +| showCheckedButton | 是否显示已选按钮 | `boolean` | true | +| checkedButtonText | 已选按钮文字 | `string` | '已选' | +| showFooter | 是否显示底部信息 | `boolean` | true | +| searchMethod `2.0.2` | 如果传入此 Prop ,触发 `search` 事件后将会执行此方法,否则会执行组件内置的搜索方法 | `(keyword: string) => void \| Promise` | 无 | +| searchLength | 触发搜索的字符长度 | `number` | 1 | +| searchDisabled | 禁用搜索功能 | `boolean` | false | +| searchRemote | 是否远程搜索,传入 `searchMethod` 时无效 | `boolean` | false | +| searchDebounceTime | 搜索防抖时间,单位为毫秒 | `number` | 300 | + +## VTreeSearch Events + +注:可在 `VTreeSearch` 上直接监听 `VTree` 的所有 Events + +| 事件名 | 说明 | 返回值 | +| :----- | :----------------- | :----------- | +| search | 执行搜索操作时触发 | 搜索的关键字 | + +## VTreeSearch Methods + +注:可在 `VTreeSearch` 上直接调用 `VTree` 的所有 Methods + +| 方法 | 说明 | 参数 | 返回值 | +| :----------- | :------------- | :------------------------------------------------------- | :-------------- | +| clearKeyword | 清空关键字 | 无 | `void` | +| getKeyword | 获取搜索关键字 | 无 | `string` | +| search | 执行搜索 | `keyword: string`: 搜索的关键字,默认为内部 this.keyword | `Promise` | + +## VTreeSearch Slots + +注:可在 `VTreeSearch` 上直接传入 `VTree` 的所有 Slots + +| 名称 | 说明 | +| :----------- | :------------------------------------------------- | +| search-input | 搜索输入框,可通过此 slot 自行封装树搜索组件的行为 | +| actions | 操作按钮,可在搜索输入框后加入更多操作按钮 | +| footer | 底部信息 | + diff --git a/site/api/vtree.md b/site/api/vtree.md new file mode 100644 index 0000000..31e691f --- /dev/null +++ b/site/api/vtree.md @@ -0,0 +1,130 @@ +# VTree API + + +## VTree Props + +| 属性 | 说明 | 类型 | 默认值 | +| :------------------------------- | :------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | +| value | 选中的值,可用 v-model ;单选为字符串或数字,多选为 `separator` 分隔的字符串或数组,优先多选 | `string \| number \| Array` | 无 | +| data | 传入的树数据。数据量大时,不建议通过 props 传入数据,建议用 `setData` 方法代替 | `object[]` | [] | +| unloadDataList | 供未加载且选中节点查询 title 字段值用的列表,格式与 `data` 一致即可 | `object[]` | [] | +| showUnloadCheckedNodes | 过滤已选时是否在列表后面展示未加载的已选节点 | `boolean` | true | +| emptyText | 数据为空时显示的文本 | `string` | '暂无数据' | +| titleField | 节点标题字段 | `string` | 'title' | +| keyField | 节点唯一标识字段 | `string` | 'id' | +| separator | 多选模式下 value 分隔符 | `string` | ',' | +| checkable | 是否可多选 | `boolean` | false | +| selectable | 是否可单选 | `boolean` | false | +| filteredNodeCheckable | 是否可勾选被过滤节点 | `boolean` | false | +| cascade | 父子节点是否关联 | `boolean` | true | +| enableLeafOnly | 是否只启用子节点,当 `多选且父子不关联` 或 `单选` 时有效 | `boolean` | false | +| disableAll | 是否禁用所有节点 | `boolean` | false | +| defaultExpandAll | 是否默认展开所有节点 | `boolean` | false | +| defaultExpandedKeys `Deprecated` | 默认展开的节点 key | `Array` | [] | +| expandedKeys `2.2.0` | 展开的节点 key ,组件内部将会响应此 Prop 的变化 | `Array` | [] | +| draggable | 是否可拖拽 | `boolean` | false | +| droppable | 是否可放置 | `boolean` | false | +| beforeDropMethod | 在放置节点之前执行的方法,返回 true 允许放置, false 可阻止放置 | `(dragKey: string \| number, dropKey: string \| number, hoverPart: 'before' \| 'body' \| 'after') => boolean` | `() => true` | +| ignoreMode | 忽略模式,指定 `getCheckedNodes`, `getCheckedKeys` 与 `v-model` 默认要忽略的部分 | `'none' \| 'parents' \| 'children'` | 'none' | +| autoLoad | 异步加载初始化时是否自动加载根节点 | `boolean` | true | +| load | 异步加载方法 | `(node: null \| TreeNode, resolve: Function, reject: Function) => any` | 无 | +| render | 节点渲染 render 函数 | `(h: CreateElement, node: TreeNode) => VNode` | 无 | +| filterMethod | 节点过滤方法 | `(keyword: string, node: TreeNode) => boolean` | 无 | +| expandOnFilter `2.1.0` | 过滤时是否展开所有可见节点 | `boolean` | true | +| unselectOnClick `2.1.0` | 点击已选中节点是否取消选中 | `boolean` | true | +| loading | 是否显示 loading 图标 | `boolean` | false | +| nodeClassName | 节点根元素的 class ,传入函数以对每个节点定制 class | `string \| object \| Array \| (node: TreeNode) => string \| object \| Array` | 无 | +| showLine `4.0.0` | 是否显示连接线,可指定连接线的宽度、颜色、实线、虚线,以及是否有折线 | `boolean \| { width?: number, type?: 'dashed' \| 'solid', color?: string, polyline?: boolean }` | 无,如果传入的非 boolean,则默认为 `{ width: 1, type: 'solid', color: '#D3D3D3', polyline: false }` | +| animation `4.0.0` | 是否启用过渡动画,目前仅控制展开收起 | `boolean` | 无 | +| nodeMinHeight | 根据节点最小高度计算数据总高度 | `number` | 30 | +| nodeIndent | 子节点缩进 | `number` | 20 | +| renderNodeAmount | 渲染节点数量,可见节点数大于此值且高度超过(容器可视高度能容纳节点数 + bufferNodeAmount)则不会渲染所有可见节点 | `number` | 100 | +| bufferNodeAmount | 当滚动到视野外的节点个数大于此值时刷新渲染节点 | `number` | 20 | + +## VTree Events + +注:从 `2.0.8` 起,事件中返回的节点信息都是包括 `_parent` 与 `children` 的完整节点信息(拖拽事件的 `dataTransfer` 除外)。 + +| 事件名 | 说明 | 返回值 | +| :--------------- | :-------------------------- | :-------------------------------------------------------------------------- | +| input | 选中节点改变时触发 | 选中的节点 | +| expand | 展开/折叠时触发 | 节点信息 | +| check | 勾选时触发(多选) | 被勾选的节点信息 | +| uncheck | 取消勾选时触发(多选) | 被取消勾选的节点信息 | +| checked-change | 勾选/取消勾选时触发(多选) | 所有被勾选节点(数组) | +| select | 选中时触发(单选) | 被选中的节点信息 | +| unselect | 取消选中时触发(单选) | 被取消选中的节点信息 | +| selected-change | 选中/取消选中时触发(单选) | 被选中节点 | +| click | 点击节点时触发 | 节点信息, 鼠标事件 | +| node-dblclick | 双击节点时触发 | 节点信息, 鼠标事件 | +| node-right-click | 右击节点时触发 | 节点信息, 鼠标事件 | +| node-dragstart | 开始拖拽节点时触发 | 节点信息, 拖拽事件对象 | +| node-dragenter | dragenter 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | +| node-dragover | dragover 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | +| node-dragleave | dragleave 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | +| node-drop | 放置节点时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | + +## VTree Methods + +| 方法 | 说明 | 参数 | 返回值 | +| :--------------------- | :---------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------- | +| setData | 使用此方法重置树数据,可避免大量数据被 vue 监听 | `data: object[]`: 同 data Prop | `void` | +| setChecked | 设置多选选中/取消选中 | `key: string \| number`: 节点 key
`value: boolean`: 是否选中 | `void` | +| setCheckedKeys | 批量设置选中/取消选中 | `keys: Array`: 节点 key
`value: boolean`: 是否选中 | `void` | +| checkAll | 设置所有数据全选 | 无 | `void` | +| clearChecked | 清空选中 | 无 | `void` | +| setSelected | 设置单选选中/取消选中 | `key: string \| number`: 节点 key
`value: boolean`: 是否选中 | `void` | +| setExpand | 设置展开/折叠 | `key: string \| number`: 节点 key
`value: boolean`: 是否展开
`expandParent: boolean = true`: 如果是展开是否同时展开父节点 `2.0.6` | `void` | +| setExpandKeys | 批量展开/折叠 | `keys: Array`: 节点 key
`value: boolean`: 是否展开 | `void` | +| setExpandAll | 设置全部展开/折叠 | `value: boolean`: 是否展开 | `void` | +| getCheckedNodes | 获取多选选中节点 | `ignoreMode: 'none' \| 'parents' \| 'children'`: 需要忽略的部分,默认为 ignoreMode Prop | `TreeNode[]` | +| getCheckedKeys | 获取多选选中节点 key | `ignoreMode: 'none' \| 'parents' \| 'children'`: 需要忽略的部分,默认为 ignoreMode Prop | `Array` | +| getIndeterminateNodes | 获取半选状态的节点 | 无 | `TreeNode[]` | +| getSelectedNode | 获取单选选中节点 | 无 | `TreeNode \| null` | +| getSelectedKey | 获取单选选中节点 key | 无 | `TreeNode \| null` | +| getExpandNodes | 获取展开的节点 | 无 | `TreeNode[]` | +| getExpandKeys | 获取展开的节点 key | 无 | `TreeNode[]` | +| getCurrentVisibleNodes | 获取当前可见的节点 | 无 | `TreeNode[]` | +| getNode | 根据 key 获取节点 | `key: string \| number`: 节点 key | `TreeNode \| null` | +| getTreeData | 获取树形结构的节点数据 | 无 | `TreeNode[]` | +| getFlatData | 获取扁平化后的节点数据 | 无 | `TreeNode[]` | +| getNodesCount | 获取节点总数量 | 无 | `number` | +| insertBefore | 在参照节点前插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`referenceKey: string \| number`: 参照节点 key | `TreeNode \| null` 返回插入的节点 | +| insertAfter | 在参照节点后插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`referenceKey: string \| number`: 参照节点 key | `TreeNode \| null` 返回插入的节点 | +| append | 在父节点第一层子节点的末尾插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`parentKey: string \| number`: 父节点 key | `TreeNode \| null` 返回插入的节点 | +| prepend | 在父节点第一层子节点的开头插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`parentKey: string \| number`: 父节点 key | `TreeNode \| null` 返回插入的节点 | +| remove | 删除节点 | `removedKey: string \| number`: 要删除的节点 key | `TreeNode \| null` 返回删除的节点 | +| filter | 过滤节点 | `keyword: string`: 过滤关键词
`filterMethod: (keyword: string, node: TreeNode) => boolean`: 过滤方法,默认为 filterMethod Prop ,如果没有传 filterMethod Prop 则为搜索 title 字段的一个内置方法 | `void` | +| showCheckedNodes | 展示已选节点 | `showUnloadCheckedNodes: boolean`: 是否显示未加载的选中节点,默认为 Prop 传入的值 | `void` | +| loadRootNodes | 从远程加载根节点 | 无 | `Promise` | +| scrollTo | 滚动到指定节点位置 | `key: string \| number`: 节点 key
`verticalPosition: 'top' \| 'center' \| 'bottom' \| number`: 滚动的垂直位置 | `void` | + +## VTree Slots + +| 名称 | 说明 | +| :----------- | :-------------------------------------------- | +| empty | 暂无数据 | +| loading | 加载中显示的图标 | +| node `4.0.0` | 自定义节点,slotProps 为 `{ node: TreeNode }` | + +## VTree Data Fields + +注:以 '`_`' 开头的字段最好不要覆盖,以免影响内部处理逻辑 + +| 字段 | 说明 | +| :-------------- | :------------------------------------------------------------------------------ | +| id | 默认以 'id' 作为 key 字段,也可以通过 `keyField` Prop 指定其他字段作为 key 字段 | +| title | 默认显示的名称,可通过 `titleField` Prop 指定其他字段作为 title 字段 | +| checked | 多选模式下是否勾选 | +| selected | 单选模式下是否选中 | +| indeterminate | 多选模式下是否半选状态 | +| disabled | 是否禁用 | +| expand | 父节点有效,节点展开状态 | +| visible | 是否可见 | +| \_filterVisible | 过滤后是否可见,如果为 false 则在其他可见情况下也是不可见的 | +| \_parent | 父节点 | +| children | 子节点数组 | +| isLeaf | 标记节点是否为叶子节点 | +| \_level | 节点层级,默认从 0 开始 | +| \_loading | 节点是否正在加载 | +| \_loaded | 节点是否已经加载过,异步加载下有效 | diff --git a/site/en/api/vtree-drop.md b/site/en/api/vtree-drop.md new file mode 100644 index 0000000..88e796d --- /dev/null +++ b/site/en/api/vtree-drop.md @@ -0,0 +1,61 @@ +# VTreeDrop API + +## VTreeDrop Props + +Note: You can use all the props of `VTree` and `VTreeSearch` in `VTreeDrop` + +| Prop | Description | Type | Default Value | +| :------------------------- | :------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- | :------------- | +| dropHeight | Height of the dropdown | `number` | 300 | +| dropPlaceholder | Placeholder of display input | `string` | 无 | +| dropDisabled | Whether to disable tree drop | `boolean` | false | +| clearable | Allow to clear | `boolean` | false | +| placement | The position of the dropdown. Note!! Does not support auto adapting directions | `'bottom-start' \| 'bottom-end' \| 'bottom' \| 'top-start' \| 'top-end' \| 'top'` | 'bottom-start' | +| transfer | To transfer DOM to body | `boolean` | false | +| dropdownClassName | Extra class on dropdown container | `string \| string[]` | 无 | +| dropdownMinWidth `2.0.1` | Min width of the dropdown. The default width is the width of the display input. It's better to use when 'transfer' is false | `number` | 无 | +| dropdownWidthFixed `2.0.5` | Fix the width of the dropdown. When the content length exceeds the min with of the dropdown, a horizontal scrollbar appears | `boolean` | false | + +## VTreeDrop Events + +Note: You can listen to all the events of `VTree` and `VTreeSearch` on `VTreeDrop` + +| Event | Description | Return Value | +| :---------------------- | :--------------------- | :------------- | +| dropdown-visible-change | Triggers when dropdown shows/hides | Visibility of the dropdown | +| clear | Triggers when click on the clear button | None | + +## VTreeDrop Methods + +Note: You can use all the methods of `VTree` and `VTreeSearch` in `VTreeDrop` + +## VTreeDrop Slots + +Note: You can pass all the slots of `VTree` and `VTreeSearch` to `VTreeDrop` + +| Name | Description | +| :------ | :--------------------------------------------------- | +| default | The whole input | +| display | The text of display input. Not effective when the default slot is present | +| clear | To replace the clear icon. Not effective when the default slot is present | + +Slot props of `default` and `display` slots `2.3.0`: + +```typescript +/** Slot props of display */ +slotProps: { + /** Multiple selected nodes */ + checkedNodes: [] as TreeNode[], + + /** Multiple selected node keys */ + checkedKeys: [] as Array, + + /** Single selected nodes */ + selectedNode: null as TreeNode | null, + + /** Single selected node keys */ + selectedKey: null as string | number | null, +}, +``` + +**Note**: `checkedNodes` and `selectedNode` only include loaded nodes. The content of these two fields will be empty if `value` prop is set but there's no tree data; While `checkedKeys` and `selectedKey` contains node keys that is not yet loaded. diff --git a/site/en/api/vtree-search.md b/site/en/api/vtree-search.md new file mode 100644 index 0000000..f8f9e80 --- /dev/null +++ b/site/en/api/vtree-search.md @@ -0,0 +1,47 @@ +# VTreeSearch API + +## VTreeSearch Props + +Note: You can use all the props of `VTree` in `VTreeSearch` + +| Prop | Description | Type | Default Value | +| :------------------- | :--------------------------------------------------------------------------------- | :------------------------------------------- | :----------- | +| searchPlaceholder | 搜索输入框的 placeholder | `string` | '搜索关键字' | +| showCheckAll | 是否显示全选复选框 | `boolean` | true | +| showCheckedButton | 是否显示已选按钮 | `boolean` | true | +| checkedButtonText | 已选按钮文字 | `string` | '已选' | +| showFooter | 是否显示底部信息 | `boolean` | true | +| searchMethod `2.0.2` | 如果传入此 Prop ,触发 `search` 事件后将会执行此方法,否则会执行组件内置的搜索方法 | `(keyword: string) => void \| Promise` | 无 | +| searchLength | 触发搜索的字符长度 | `number` | 1 | +| searchDisabled | 禁用搜索功能 | `boolean` | false | +| searchRemote | 是否远程搜索,传入 `searchMethod` 时无效 | `boolean` | false | +| searchDebounceTime | 搜索防抖时间,单位为毫秒 | `number` | 300 | + +## VTreeSearch Events + +Note: You can listen to all the events of `VTree` on `VTreeSearch` + +| Event | Description | Return Value | +| :----- | :----------------- | :----------- | +| search | 执行搜索操作时触发 | 搜索的关键字 | + +## VTreeSearch Methods + +Note: You can use all the methods of `VTree` in `VTreeSearch` + +| Method | Description | Params | Return Value | +| :----------- | :------------- | :------------------------------------------------------- | :-------------- | +| clearKeyword | 清空关键字 | 无 | `void` | +| getKeyword | 获取搜索关键字 | 无 | `string` | +| search | 执行搜索 | `keyword: string`: 搜索的关键字,默认为内部 this.keyword | `Promise` | + +## VTreeSearch Slots + +Note: You can pass all the slots of `VTree` to `VTreeSearch` + +| Name | Description | +| :----------- | :------------------------------------------------- | +| search-input | 搜索输入框,可通过此 slot 自行封装树搜索组件的行为 | +| actions | 操作按钮,可在搜索输入框后加入更多操作按钮 | +| footer | 底部信息 | + diff --git a/site/en/api/vtree.md b/site/en/api/vtree.md new file mode 100644 index 0000000..53206b9 --- /dev/null +++ b/site/en/api/vtree.md @@ -0,0 +1,130 @@ +# VTree API + + +## VTree Props + +| Prop | Description | Type | Default Value | +| :------------------------------- | :------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | +| value | 选中的值,可用 v-model ;单选为字符串或数字,多选为 `separator` 分隔的字符串或数组,优先多选 | `string \| number \| Array` | 无 | +| data | 传入的树数据。数据量大时,不建议通过 props 传入数据,建议用 `setData` 方法代替 | `object[]` | [] | +| unloadDataList | 供未加载且选中节点查询 title 字段值用的列表,格式与 `data` 一致即可 | `object[]` | [] | +| showUnloadCheckedNodes | 过滤已选时是否在列表后面展示未加载的已选节点 | `boolean` | true | +| emptyText | 数据为空时显示的文本 | `string` | '暂无数据' | +| titleField | 节点标题字段 | `string` | 'title' | +| keyField | 节点唯一标识字段 | `string` | 'id' | +| separator | 多选模式下 value 分隔符 | `string` | ',' | +| checkable | 是否可多选 | `boolean` | false | +| selectable | 是否可单选 | `boolean` | false | +| filteredNodeCheckable | 是否可勾选被过滤节点 | `boolean` | false | +| cascade | 父子节点是否关联 | `boolean` | true | +| enableLeafOnly | 是否只启用子节点,当 `多选且父子不关联` 或 `单选` 时有效 | `boolean` | false | +| disableAll | 是否禁用所有节点 | `boolean` | false | +| defaultExpandAll | 是否默认展开所有节点 | `boolean` | false | +| defaultExpandedKeys `Deprecated` | 默认展开的节点 key | `Array` | [] | +| expandedKeys `2.2.0` | 展开的节点 key ,组件内部将会响应此 Prop 的变化 | `Array` | [] | +| draggable | 是否可拖拽 | `boolean` | false | +| droppable | 是否可放置 | `boolean` | false | +| beforeDropMethod | 在放置节点之前执行的方法,返回 true 允许放置, false 可阻止放置 | `(dragKey: string \| number, dropKey: string \| number, hoverPart: 'before' \| 'body' \| 'after') => boolean` | `() => true` | +| ignoreMode | 忽略模式,指定 `getCheckedNodes`, `getCheckedKeys` 与 `v-model` 默认要忽略的部分 | `'none' \| 'parents' \| 'children'` | 'none' | +| autoLoad | 异步加载初始化时是否自动加载根节点 | `boolean` | true | +| load | 异步加载方法 | `(node: null \| TreeNode, resolve: Function, reject: Function) => any` | 无 | +| render | 节点渲染 render 函数 | `(h: CreateElement, node: TreeNode) => VNode` | 无 | +| filterMethod | 节点过滤方法 | `(keyword: string, node: TreeNode) => boolean` | 无 | +| expandOnFilter `2.1.0` | 过滤时是否展开所有可见节点 | `boolean` | true | +| unselectOnClick `2.1.0` | 点击已选中节点是否取消选中 | `boolean` | true | +| loading | 是否显示 loading 图标 | `boolean` | false | +| nodeClassName | 节点根元素的 class ,传入函数以对每个节点定制 class | `string \| object \| Array \| (node: TreeNode) => string \| object \| Array` | 无 | +| showLine `4.0.0` | 是否显示连接线,可指定连接线的宽度、颜色、实线、虚线,以及是否有折线 | `boolean \| { width?: number, type?: 'dashed' \| 'solid', color?: string, polyline?: boolean }` | 无,如果传入的非 boolean,则默认为 `{ width: 1, type: 'solid', color: '#D3D3D3', polyline: false }` | +| animation `4.0.0` | 是否启用过渡动画,目前仅控制展开收起 | `boolean` | 无 | +| nodeMinHeight | 根据节点最小高度计算数据总高度 | `number` | 30 | +| nodeIndent | 子节点缩进 | `number` | 20 | +| renderNodeAmount | 渲染节点数量,可见节点数大于此值且高度超过(容器可视高度能容纳节点数 + bufferNodeAmount)则不会渲染所有可见节点 | `number` | 100 | +| bufferNodeAmount | 当滚动到视野外的节点个数大于此值时刷新渲染节点 | `number` | 20 | + +## VTree Events + +注:从 `2.0.8` 起,事件中返回的节点信息都是包括 `_parent` 与 `children` 的完整节点信息(拖拽事件的 `dataTransfer` 除外)。 + +| Event | Description | Return Value | +| :--------------- | :-------------------------- | :-------------------------------------------------------------------------- | +| input | 选中节点改变时触发 | 选中的节点 | +| expand | 展开/折叠时触发 | 节点信息 | +| check | 勾选时触发(多选) | 被勾选的节点信息 | +| uncheck | 取消勾选时触发(多选) | 被取消勾选的节点信息 | +| checked-change | 勾选/取消勾选时触发(多选) | 所有被勾选节点(数组) | +| select | 选中时触发(单选) | 被选中的节点信息 | +| unselect | 取消选中时触发(单选) | 被取消选中的节点信息 | +| selected-change | 选中/取消选中时触发(单选) | 被选中节点 | +| click | 点击节点时触发 | 节点信息, 鼠标事件 | +| node-dblclick | 双击节点时触发 | 节点信息, 鼠标事件 | +| node-right-click | 右击节点时触发 | 节点信息, 鼠标事件 | +| node-dragstart | 开始拖拽节点时触发 | 节点信息, 拖拽事件对象 | +| node-dragenter | dragenter 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | +| node-dragover | dragover 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | +| node-dragleave | dragleave 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | +| node-drop | 放置节点时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | + +## VTree Methods + +| Method | Description | Params | Return Value | +| :--------------------- | :---------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------- | +| setData | 使用此方法重置树数据,可避免大量数据被 vue 监听 | `data: object[]`: 同 data Prop | `void` | +| setChecked | 设置多选选中/取消选中 | `key: string \| number`: 节点 key
`value: boolean`: 是否选中 | `void` | +| setCheckedKeys | 批量设置选中/取消选中 | `keys: Array`: 节点 key
`value: boolean`: 是否选中 | `void` | +| checkAll | 设置所有数据全选 | 无 | `void` | +| clearChecked | 清空选中 | 无 | `void` | +| setSelected | 设置单选选中/取消选中 | `key: string \| number`: 节点 key
`value: boolean`: 是否选中 | `void` | +| setExpand | 设置展开/折叠 | `key: string \| number`: 节点 key
`value: boolean`: 是否展开
`expandParent: boolean = true`: 如果是展开是否同时展开父节点 `2.0.6` | `void` | +| setExpandKeys | 批量展开/折叠 | `keys: Array`: 节点 key
`value: boolean`: 是否展开 | `void` | +| setExpandAll | 设置全部展开/折叠 | `value: boolean`: 是否展开 | `void` | +| getCheckedNodes | 获取多选选中节点 | `ignoreMode: 'none' \| 'parents' \| 'children'`: 需要忽略的部分,默认为 ignoreMode Prop | `TreeNode[]` | +| getCheckedKeys | 获取多选选中节点 key | `ignoreMode: 'none' \| 'parents' \| 'children'`: 需要忽略的部分,默认为 ignoreMode Prop | `Array` | +| getIndeterminateNodes | 获取半选状态的节点 | 无 | `TreeNode[]` | +| getSelectedNode | 获取单选选中节点 | 无 | `TreeNode \| null` | +| getSelectedKey | 获取单选选中节点 key | 无 | `TreeNode \| null` | +| getExpandNodes | 获取展开的节点 | 无 | `TreeNode[]` | +| getExpandKeys | 获取展开的节点 key | 无 | `TreeNode[]` | +| getCurrentVisibleNodes | 获取当前可见的节点 | 无 | `TreeNode[]` | +| getNode | 根据 key 获取节点 | `key: string \| number`: 节点 key | `TreeNode \| null` | +| getTreeData | 获取树形结构的节点数据 | 无 | `TreeNode[]` | +| getFlatData | 获取扁平化后的节点数据 | 无 | `TreeNode[]` | +| getNodesCount | 获取节点总数量 | 无 | `number` | +| insertBefore | 在参照节点前插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`referenceKey: string \| number`: 参照节点 key | `TreeNode \| null` 返回插入的节点 | +| insertAfter | 在参照节点后插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`referenceKey: string \| number`: 参照节点 key | `TreeNode \| null` 返回插入的节点 | +| append | 在父节点第一层子节点的末尾插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`parentKey: string \| number`: 父节点 key | `TreeNode \| null` 返回插入的节点 | +| prepend | 在父节点第一层子节点的开头插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`parentKey: string \| number`: 父节点 key | `TreeNode \| null` 返回插入的节点 | +| remove | 删除节点 | `removedKey: string \| number`: 要删除的节点 key | `TreeNode \| null` 返回删除的节点 | +| filter | 过滤节点 | `keyword: string`: 过滤关键词
`filterMethod: (keyword: string, node: TreeNode) => boolean`: 过滤方法,默认为 filterMethod Prop ,如果没有传 filterMethod Prop 则为搜索 title 字段的一个内置方法 | `void` | +| showCheckedNodes | 展示已选节点 | `showUnloadCheckedNodes: boolean`: 是否显示未加载的选中节点,默认为 Prop 传入的值 | `void` | +| loadRootNodes | 从远程加载根节点 | 无 | `Promise` | +| scrollTo | 滚动到指定节点位置 | `key: string \| number`: 节点 key
`verticalPosition: 'top' \| 'center' \| 'bottom' \| number`: 滚动的垂直位置 | `void` | + +## VTree Slots + +| Name | Description | +| :----------- | :-------------------------------------------- | +| empty | 暂无数据 | +| loading | 加载中显示的图标 | +| node `4.0.0` | 自定义节点,slotProps 为 `{ node: TreeNode }` | + +## VTree Data Fields + +Note: It's better not to override the fields starting with '`_`' to avoid the impact on the internal logic + +| Field | Description | +| :-------------- | :------------------------------------------------------------------------------ | +| id | 默认以 'id' 作为 key 字段,也可以通过 `keyField` Prop 指定其他字段作为 key 字段 | +| title | 默认显示的名称,可通过 `titleField` Prop 指定其他字段作为 title 字段 | +| checked | 多选模式下是否勾选 | +| selected | 单选模式下是否选中 | +| indeterminate | 多选模式下是否半选状态 | +| disabled | 是否禁用 | +| expand | 父节点有效,节点展开状态 | +| visible | 是否可见 | +| \_filterVisible | 过滤后是否可见,如果为 false 则在其他可见情况下也是不可见的 | +| \_parent | 父节点 | +| children | 子节点数组 | +| isLeaf | 标记节点是否为叶子节点 | +| \_level | 节点层级,默认从 0 开始 | +| \_loading | 节点是否正在加载 | +| \_loaded | 节点是否已经加载过,异步加载下有效 | diff --git a/site/en/examples/node-manipulation.md b/site/en/examples/node-manipulation.md new file mode 100644 index 0000000..5e4f92e --- /dev/null +++ b/site/en/examples/node-manipulation.md @@ -0,0 +1,24 @@ +# Node Manipulation {#node-manipulation} + +## Custom Node {#custom-node} + +There are two ways of customizing nodes: + +1. Use named slot `node` +2. Use `render` prop + + + +## Drag and Drop {#drag-and-drop} + +Enable `draggable` and `droppable` + + + +## Node Creation and Removal {#node-creation-and-removal} + +- Invoke `insertBefore`, `insertAfter` method of tree component to insert new node before and after tree nodes +- Invoke `prepend`, `append` method of tree component to prepend or append to child list +- Invoke `remove` to remove a node + + diff --git a/site/en/examples/performance.md b/site/en/examples/performance.md new file mode 100644 index 0000000..c22323d --- /dev/null +++ b/site/en/examples/performance.md @@ -0,0 +1,7 @@ +# Performance {#performance} + +1. Works fine in Chrome +2. There's a max height limitation of browser element/document. Issues may occur when the data is way too large +3. It takes time to generate nodes, so please be aware of the depth of the tree when you config + + diff --git a/site/en/examples/tree-drop.md b/site/en/examples/tree-drop.md new file mode 100644 index 0000000..ad3a35e --- /dev/null +++ b/site/en/examples/tree-drop.md @@ -0,0 +1,19 @@ +# Tree Drop {#tree-drop} + +## Basic Drop {#basic-drop} + +Use `VTreeDrop` component to use tree in a dropdown + + + +## Customize Display of Input Content {#custom-drop-display} + +You can use `display` slot to customize the text value of input + + + +## Customize the Whole Dropdown Input {#custom-drop-input} + +Use the default slot to replace the whole input component of the dropdown + + diff --git a/site/en/examples/tree-search.md b/site/en/examples/tree-search.md new file mode 100644 index 0000000..740dc7a --- /dev/null +++ b/site/en/examples/tree-search.md @@ -0,0 +1,19 @@ +# Tree Search {#tree-search} + +## Local Search {#local-search} + +Use `VTreeSearch` component to search + + + +## Remote Search {#remote-search} + +Use `searchRemote` along with `load` method to search from remote + + + +## Actions Slot {#actions-slot} + +Use `actions` slot to customize action buttons + + diff --git a/site/en/examples/tree.md b/site/en/examples/tree.md new file mode 100644 index 0000000..3b173e5 --- /dev/null +++ b/site/en/examples/tree.md @@ -0,0 +1,58 @@ +# Basic Usage {#basic-usage} + +## Data Display {#data-display} + +`data` prop can be accepted. To prevent from performance issue, use `setData` when the data is large. + + + +## Single Select {#selectable} + +Use `selectable` to enable single select + + + +## Multiple Select {#checkable} + +Use `checkable` to enable multiple select + + + +## Ignore Specific Nodes {#ignore-mode} + +Parent nodes or child nodes can be ignored in `v-model` and `getCheckedNodes` using `ignoreMode` prop. This prop is effective only when it's set initially. + + + +## Node Cascade {#cascade} + +Use `cascade` to config if parent and child nodes are cascaded + + + +## Single and Multiple Select {#selectable-and-checkable} + +When single and multiple select are enabled at the same time, the value of `v-model` is bound to multiple select value + + + +## Expand Animation {#expand-animation} + +Use `animation` to enable animation when expand/collapse + + + +## Connecting Line {#show-line} + +Use `showLine` to show lines between nodes + +Apart from `boolean`, the `showLine` prop also takes an object to config the type, width, color and polyline of the line + + + +## Remote {#remote} + +Config `load` method to load data from remote. `data` prop will be used as root data if present; +If there's no `data`, then `load` will be invoked to load root data with a `null` node parameter + + diff --git a/site/en/guide/getting-started.md b/site/en/guide/getting-started.md new file mode 100644 index 0000000..0689efc --- /dev/null +++ b/site/en/guide/getting-started.md @@ -0,0 +1,38 @@ +# Getting Started {#getting-started} + +## Try It Online {#try-it-online} + +
Refer to to try it online
+ +## Install {#install} + +```bash +# npm +npm install @wsfe/vue-tree + +# yarn +yarn add @wsfe/vue-tree + +# pnpm +pnpm add @wsfe/vue-tree +``` + +## Import {#import} + +`@wsfe/vue-tree` Provides three components + +```typescript +import VTree, { VTreeSearch, VTreeDrop } from '@wsfe/vue-tree' +``` + +Import style + +```css +@import '~@wsfe/vue-tree/style.css'; +``` + +Import less to override variables + +```less +@import '~@wsfe/vue-tree/src/styles/index.less'; +``` diff --git a/site/en/guide/migration.md b/site/en/guide/migration.md new file mode 100644 index 0000000..e1a9b9c --- /dev/null +++ b/site/en/guide/migration.md @@ -0,0 +1,23 @@ +# Migrate from Old Version {#migrate-from-old-version} + +## Vue Support {#vue-support} + +`@wsfe/vue-tree` is the upgraded version of `@wsfe/ctree`. The new version changed the exported module names and Less/CSS prefixes. + +Vue support info: + +- @wsfe/vue-tree 4.x: Vue3 +- @wsfe/vue-tree 3.x: Supports Vue2 and Vue3 using `vue-demi`, but it's not under maintenance due to compatibility issues +- @wsfe/ctree: Vue2. Severe bug fixes only + +## Migration {#migration} + +To migrate from `@wsfe/ctree` or `@wsfe/vue-tree` 3.x to `@wsfe/vue-tree` 4.x, follow these steps: + +1. Update all Less variables and CSS related class prefix from ctree to vtree +2. Change the prefix of exported modules from C to V + +```typescript +import CTree, { CTreeSearch, CTreeDrop } from '@wsfe/ctree' // [!code --] +import VTree, { VTreeSearch, VTreeDrop } from '@wsfe/vue-tree' // [!code ++] +``` diff --git a/site/en/index.md b/site/en/index.md new file mode 100644 index 0000000..3bb5dba --- /dev/null +++ b/site/en/index.md @@ -0,0 +1,28 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "Vue Tree" + text: "Vue tree component optimized using virtual list" + tagline: 🌲@wsfe/vue-tree + actions: + - theme: brand + text: Getting Started + link: /en/guide/getting-started + - theme: alt + text: API Document + link: /en/api/vtree + +features: + - icon: 🚀 + title: Virtual List + details: Optimized using virtual list, handles large data loads + - icon: 📝 + title: Rich Features + details: Supports tree display, single select, multiple select, search, dropdown, remote loading and drap-and-drop, etc. + - icon: + title: Vue3 + details: Supports Vue3 +--- + diff --git a/site/examples/node-manipulation.md b/site/examples/node-manipulation.md new file mode 100644 index 0000000..36a1e41 --- /dev/null +++ b/site/examples/node-manipulation.md @@ -0,0 +1,24 @@ +# 节点操作 {#node-manipulation} + +## 自定义节点 {#custom-node} + +有两种自定义节点的方式: + +1. 传入具名插槽 `node` +2. 使用 `render` Prop + + + +## 拖拽 {#drag-and-drop} + +启用 `draggable` 与 `droppable` 可实现拖拽功能 + + + +## 节点新增与删除 {#node-creation-and-removal} + +- 调用树组件的 `insertBefore`, `insertAfter` 方法,可在节点前后插入新的节点 +- 调用树组件的 `prepend`, `append` 方法,可插入新的节点到子节点列表的最前面或最后面 +- 调用树组件的 `remove` 方法,可移除节点 + + diff --git a/site/examples/performance.md b/site/examples/performance.md new file mode 100644 index 0000000..467c18e --- /dev/null +++ b/site/examples/performance.md @@ -0,0 +1,7 @@ +# 性能测试 {#performance} + +1. 在 Chrome 下表现良好 +2. 浏览器元素/文档是有最大高度限制的,过多数据会导致显示不正常 +3. 生成节点比较耗时,请注意节点深度 + + diff --git a/site/examples/tree-drop.md b/site/examples/tree-drop.md new file mode 100644 index 0000000..b5d9caf --- /dev/null +++ b/site/examples/tree-drop.md @@ -0,0 +1,19 @@ +# 树下拉 {#tree-drop} + +## 基础下拉 {#basic-drop} + +使用 `VTreeDrop` 组件可实现树下拉 + + + +## 自定义输入框展示 {#custom-drop-display} + +如果想自定义展示输入框选中的值,可使用 `display` 插槽 + + + +## 自定义整个输入框 {#custom-drop-input} + +使用默认插槽可把整个输入框替换掉 + + diff --git a/site/examples/tree-search.md b/site/examples/tree-search.md new file mode 100644 index 0000000..1c564d8 --- /dev/null +++ b/site/examples/tree-search.md @@ -0,0 +1,19 @@ +# 树搜索 {#tree-search} + +## 本地搜索 {#local-search} + +使用 `VTreeSearch` 组件可实现树搜索功能 + + + +## 远程搜索 {#remote-search} + +启用 `searchRemote` 并配合 `load` 方法,可实现远程搜索 + + + +## 操作插槽 {#actions-slot} + +使用 `actions` 插槽可定制功能按钮 + + diff --git a/site/examples/tree.md b/site/examples/tree.md new file mode 100644 index 0000000..8fe9316 --- /dev/null +++ b/site/examples/tree.md @@ -0,0 +1,58 @@ +# 基本用法 {#basic-usage} + +## 数据展示 {#data-display} + +可直接传入 `data` Prop。当数据量较大时,为了防止 Vue 监听过多数据导致性能问题,可使用 `setData` 方法设置数据。 + + + +## 单选 {#selectable} + +使用 `selectable` 启用单选功能 + + + +## 多选 {#checkable} + +使用 `checkable` 启用单选功能 + + + +## 多选忽略特定节点 {#ignore-mode} + +配置 `ignoreMode` 可在 `v-model` 和 `getCheckedNodes` 方法忽略父节点或者子节点,该 Prop 仅初始设置有效 + + + +## 父子节点级联 {#cascade} + +配置 `cascade` 可指定父子节点是否级联 + + + +## 单选与多选并存 {#selectable-and-checkable} + +当既可以单选又可以多选时, `v-model` 绑定的是多选的值 + + + +## 展开动画 {#expand-animation} + +配置 `animation` 可开启展开收起动画 + + + +## 连接线 {#show-line} + +配置 `showLine` 可开启连接线 + +`showLine` 除了 `boolean`,还可以接收一个对象用于具体配置连接线的类型、宽度、颜色与是否启用折线 + + + +## 远程 {#remote} + +设置 `load` 方法可以使用远程加载数据,如果有设置 `data`,则 `data` 数据作为根数据; +如果没有传 `data`,则初始化时调用 `load` 方法载入根数据,其中节点参数为 `null` + + diff --git a/site/guide/getting-started.md b/site/guide/getting-started.md new file mode 100644 index 0000000..c33f153 --- /dev/null +++ b/site/guide/getting-started.md @@ -0,0 +1,38 @@ +# 快速开始 {#getting-started} + +## 在线尝试 {#try-it-online} + +
前往 在线尝试
+ +## 安装 {#install} + +```bash +# npm +npm install @wsfe/vue-tree + +# yarn +yarn add @wsfe/vue-tree + +# pnpm +pnpm add @wsfe/vue-tree +``` + +## 引入 {#import} + +`@wsfe/vue-tree` 提供了三个组件 + +```typescript +import VTree, { VTreeSearch, VTreeDrop } from '@wsfe/vue-tree' +``` + +引入样式 + +```css +@import '~@wsfe/vue-tree/style.css'; +``` + +引入 less 以便于变量覆盖 + +```less +@import '~@wsfe/vue-tree/src/styles/index.less'; +``` diff --git a/site/guide/migration.md b/site/guide/migration.md new file mode 100644 index 0000000..680bc47 --- /dev/null +++ b/site/guide/migration.md @@ -0,0 +1,23 @@ +# 从旧版迁移 {#migrate-from-old-version} + +## Vue 支持情况 {#vue-support} + +`@wsfe/vue-tree` 是 `@wsfe/ctree` 的升级版,新旧版本之间除了包的名称,导出的模块与 Less/CSS 相关前缀也有所不同 + +对 Vue 的支持情况如下: + +- @wsfe/vue-tree 4.x: 支持 Vue3 +- @wsfe/vue-tree 3.x: 使用 `vue-demi` 同时支持 Vue2 与 Vue3,但存在 Vue2 兼容性问题,后续不会再维护 +- @wsfe/ctree: 支持 Vue2,后续仅提供重大 bug 修复 + +## 迁移 {#migration} + +从 `@wsfe/ctree` 或者 `@wsfe/vue-tree` 3.x 迁移到 `@wsfe/vue-tree` 4.x 需按如下步骤修改: + +1. 所有 Less 变量与 CSS 相关 class 前缀从 ctree 改为 vtree +2. 导出的包前缀从 C 改为 V,例如: + +```typescript +import CTree, { CTreeSearch, CTreeDrop } from '@wsfe/ctree' // [!code --] +import VTree, { VTreeSearch, VTreeDrop } from '@wsfe/vue-tree' // [!code ++] +``` diff --git a/site/index.md b/site/index.md new file mode 100644 index 0000000..5b7ca57 --- /dev/null +++ b/site/index.md @@ -0,0 +1,28 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "Vue Tree" + text: "使用虚拟列表优化的 Vue 树组件" + tagline: 🌲@wsfe/vue-tree + actions: + - theme: brand + text: 开始使用 + link: /guide/getting-started + - theme: alt + text: API 文档 + link: /api/vtree + +features: + - icon: 🚀 + title: 虚拟列表 + details: 使用虚拟列表优化,可加载大量数据 + - icon: 📝 + title: 丰富特性 + details: 支持树形展示,单多选,搜索,下拉,远程加载,拖拽等 + - icon: + title: Vue3 + details: 支持 Vue3 +--- + diff --git a/site/package.json b/site/package.json new file mode 100644 index 0000000..0afed5f --- /dev/null +++ b/site/package.json @@ -0,0 +1,9 @@ +{ + "name": "@wsfe/vue-tree-site", + "version": "0.1.0", + "type": "module", + "dependencies": { + "@vue/repl": "^4.2.1", + "@wsfe/vue-tree": "^4.0.0" + } +} \ No newline at end of file diff --git a/site/playground.md b/site/playground.md new file mode 100644 index 0000000..2af4ceb --- /dev/null +++ b/site/playground.md @@ -0,0 +1,11 @@ +--- +layout: page +navbar: false +sidebar: false +--- + + + + diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml new file mode 100644 index 0000000..688c535 --- /dev/null +++ b/site/pnpm-lock.yaml @@ -0,0 +1,23 @@ +lockfileVersion: '6.1' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@vue/repl': + specifier: ^4.2.1 + version: 4.2.1 + '@wsfe/vue-tree': + specifier: ^4.0.0 + version: 4.0.0 + +packages: + + /@vue/repl@4.2.1: + resolution: {integrity: sha512-kPpoAp0hQ1sKIGXEHtVdtdh2BgL97SAizEvCqRDB3LmgIYCPbzInwd4mqYkHstAhJPmkNslLd3rwfceMwzwinQ==} + dev: false + + /@wsfe/vue-tree@4.0.0: + resolution: {integrity: sha512-gFHQmvHCky5LHs4MinBc+kZsInf/sU8GFdyy4QZvCrII5yQfjkEF4TpSYG1SZFnPAN2ZOvFvJq5aDlT3X8rQmA==} + dev: false From 5f41b35860606321fd9697d082d53f48db70f058 Mon Sep 17 00:00:00 2001 From: ChuChencheng Date: Tue, 2 Jul 2024 00:07:02 +0800 Subject: [PATCH 2/3] doc: translation --- site/en/api/vtree-drop.md | 38 +++--- site/en/api/vtree-search.md | 50 ++++---- site/en/api/vtree.md | 222 ++++++++++++++++++------------------ site/en/guide/migration.md | 4 +- site/guide/migration.md | 4 +- 5 files changed, 159 insertions(+), 159 deletions(-) diff --git a/site/en/api/vtree-drop.md b/site/en/api/vtree-drop.md index 88e796d..83fc98c 100644 --- a/site/en/api/vtree-drop.md +++ b/site/en/api/vtree-drop.md @@ -4,26 +4,26 @@ Note: You can use all the props of `VTree` and `VTreeSearch` in `VTreeDrop` -| Prop | Description | Type | Default Value | -| :------------------------- | :------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- | :------------- | -| dropHeight | Height of the dropdown | `number` | 300 | -| dropPlaceholder | Placeholder of display input | `string` | 无 | -| dropDisabled | Whether to disable tree drop | `boolean` | false | -| clearable | Allow to clear | `boolean` | false | -| placement | The position of the dropdown. Note!! Does not support auto adapting directions | `'bottom-start' \| 'bottom-end' \| 'bottom' \| 'top-start' \| 'top-end' \| 'top'` | 'bottom-start' | -| transfer | To transfer DOM to body | `boolean` | false | -| dropdownClassName | Extra class on dropdown container | `string \| string[]` | 无 | -| dropdownMinWidth `2.0.1` | Min width of the dropdown. The default width is the width of the display input. It's better to use when 'transfer' is false | `number` | 无 | -| dropdownWidthFixed `2.0.5` | Fix the width of the dropdown. When the content length exceeds the min with of the dropdown, a horizontal scrollbar appears | `boolean` | false | +| Prop | Description | Type | Default Value | +| :------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- | :------------- | +| dropHeight | Height of the dropdown | `number` | 300 | +| dropPlaceholder | Placeholder of display input | `string` | None | +| dropDisabled | Whether to disable tree drop | `boolean` | false | +| clearable | Allow to clear | `boolean` | false | +| placement | The position of the dropdown. Note!! Does not support auto adapting directions | `'bottom-start' \| 'bottom-end' \| 'bottom' \| 'top-start' \| 'top-end' \| 'top'` | 'bottom-start' | +| transfer | To transfer DOM to body | `boolean` | false | +| dropdownClassName | Extra class on dropdown container | `string \| string[]` | None | +| dropdownMinWidth `2.0.1` | Min width of the dropdown. The default width is the width of the display input. It's better to use when 'transfer' is false | `number` | None | +| dropdownWidthFixed `2.0.5` | Fix the width of the dropdown. When the content length exceeds the min with of the dropdown, a horizontal scrollbar appears | `boolean` | false | ## VTreeDrop Events Note: You can listen to all the events of `VTree` and `VTreeSearch` on `VTreeDrop` -| Event | Description | Return Value | -| :---------------------- | :--------------------- | :------------- | -| dropdown-visible-change | Triggers when dropdown shows/hides | Visibility of the dropdown | -| clear | Triggers when click on the clear button | None | +| Event | Description | Return Value | +| :---------------------- | :-------------------------------------- | :------------------------- | +| dropdown-visible-change | Triggers when dropdown shows/hides | Visibility of the dropdown | +| clear | Triggers when click on the clear button | None | ## VTreeDrop Methods @@ -33,11 +33,11 @@ Note: You can use all the methods of `VTree` and `VTreeSearch` in `VTreeDrop` Note: You can pass all the slots of `VTree` and `VTreeSearch` to `VTreeDrop` -| Name | Description | -| :------ | :--------------------------------------------------- | -| default | The whole input | +| Name | Description | +| :------ | :------------------------------------------------------------------------ | +| default | The whole input | | display | The text of display input. Not effective when the default slot is present | -| clear | To replace the clear icon. Not effective when the default slot is present | +| clear | To replace the clear icon. Not effective when the default slot is present | Slot props of `default` and `display` slots `2.3.0`: diff --git a/site/en/api/vtree-search.md b/site/en/api/vtree-search.md index f8f9e80..1a0f978 100644 --- a/site/en/api/vtree-search.md +++ b/site/en/api/vtree-search.md @@ -4,44 +4,44 @@ Note: You can use all the props of `VTree` in `VTreeSearch` -| Prop | Description | Type | Default Value | -| :------------------- | :--------------------------------------------------------------------------------- | :------------------------------------------- | :----------- | -| searchPlaceholder | 搜索输入框的 placeholder | `string` | '搜索关键字' | -| showCheckAll | 是否显示全选复选框 | `boolean` | true | -| showCheckedButton | 是否显示已选按钮 | `boolean` | true | -| checkedButtonText | 已选按钮文字 | `string` | '已选' | -| showFooter | 是否显示底部信息 | `boolean` | true | -| searchMethod `2.0.2` | 如果传入此 Prop ,触发 `search` 事件后将会执行此方法,否则会执行组件内置的搜索方法 | `(keyword: string) => void \| Promise` | 无 | -| searchLength | 触发搜索的字符长度 | `number` | 1 | -| searchDisabled | 禁用搜索功能 | `boolean` | false | -| searchRemote | 是否远程搜索,传入 `searchMethod` 时无效 | `boolean` | false | -| searchDebounceTime | 搜索防抖时间,单位为毫秒 | `number` | 300 | +| Prop | Description | Type | Default Value | +| :------------------- | :---------------------------------------------------------------------------------------------------------------------- | :------------------------------------------- | :------------ | +| searchPlaceholder | Placeholder of search input | `string` | '搜索关键字' | +| showCheckAll | Whether to show check all checkbox | `boolean` | true | +| showCheckedButton | Whether to show 'Checked' button | `boolean` | true | +| checkedButtonText | Checked button text | `string` | '已选' | +| showFooter | Whether to show footer | `boolean` | true | +| searchMethod `2.0.2` | This method will be invoked when `search` event triggers if present, or else the internal search method will be invoked | `(keyword: string) => void \| Promise` | None | +| searchLength | The length of search text that triggers a search | `number` | 1 | +| searchDisabled | Disable search | `boolean` | false | +| searchRemote | Enable remote search. Not effective when `searchMethod` is present | `boolean` | false | +| searchDebounceTime | Search debounce time. Unit: ms | `number` | 300 | ## VTreeSearch Events Note: You can listen to all the events of `VTree` on `VTreeSearch` -| Event | Description | Return Value | -| :----- | :----------------- | :----------- | -| search | 执行搜索操作时触发 | 搜索的关键字 | +| Event | Description | Return Value | +| :----- | :------------------- | :------------- | +| search | Triggers when search | Search keyword | ## VTreeSearch Methods Note: You can use all the methods of `VTree` in `VTreeSearch` -| Method | Description | Params | Return Value | -| :----------- | :------------- | :------------------------------------------------------- | :-------------- | -| clearKeyword | 清空关键字 | 无 | `void` | -| getKeyword | 获取搜索关键字 | 无 | `string` | -| search | 执行搜索 | `keyword: string`: 搜索的关键字,默认为内部 this.keyword | `Promise` | +| Method | Description | Params | Return Value | +| :----------- | :------------- | :---------------------------------------------------------------------------- | :-------------- | +| clearKeyword | Clear keyword | None | `void` | +| getKeyword | Get keyword | None | `string` | +| search | Execute search | `keyword: string`: Search keyword, the default value is internal this.keyword | `Promise` | ## VTreeSearch Slots Note: You can pass all the slots of `VTree` to `VTreeSearch` -| Name | Description | -| :----------- | :------------------------------------------------- | -| search-input | 搜索输入框,可通过此 slot 自行封装树搜索组件的行为 | -| actions | 操作按钮,可在搜索输入框后加入更多操作按钮 | -| footer | 底部信息 | +| Name | Description | +| :----------- | :------------------------------------------------------------ | +| search-input | Search input | +| actions | Action buttons. Append more action buttons after search input | +| footer | Footer info | diff --git a/site/en/api/vtree.md b/site/en/api/vtree.md index 53206b9..8106f40 100644 --- a/site/en/api/vtree.md +++ b/site/en/api/vtree.md @@ -3,128 +3,128 @@ ## VTree Props -| Prop | Description | Type | Default Value | -| :------------------------------- | :------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | -| value | 选中的值,可用 v-model ;单选为字符串或数字,多选为 `separator` 分隔的字符串或数组,优先多选 | `string \| number \| Array` | 无 | -| data | 传入的树数据。数据量大时,不建议通过 props 传入数据,建议用 `setData` 方法代替 | `object[]` | [] | -| unloadDataList | 供未加载且选中节点查询 title 字段值用的列表,格式与 `data` 一致即可 | `object[]` | [] | -| showUnloadCheckedNodes | 过滤已选时是否在列表后面展示未加载的已选节点 | `boolean` | true | -| emptyText | 数据为空时显示的文本 | `string` | '暂无数据' | -| titleField | 节点标题字段 | `string` | 'title' | -| keyField | 节点唯一标识字段 | `string` | 'id' | -| separator | 多选模式下 value 分隔符 | `string` | ',' | -| checkable | 是否可多选 | `boolean` | false | -| selectable | 是否可单选 | `boolean` | false | -| filteredNodeCheckable | 是否可勾选被过滤节点 | `boolean` | false | -| cascade | 父子节点是否关联 | `boolean` | true | -| enableLeafOnly | 是否只启用子节点,当 `多选且父子不关联` 或 `单选` 时有效 | `boolean` | false | -| disableAll | 是否禁用所有节点 | `boolean` | false | -| defaultExpandAll | 是否默认展开所有节点 | `boolean` | false | -| defaultExpandedKeys `Deprecated` | 默认展开的节点 key | `Array` | [] | -| expandedKeys `2.2.0` | 展开的节点 key ,组件内部将会响应此 Prop 的变化 | `Array` | [] | -| draggable | 是否可拖拽 | `boolean` | false | -| droppable | 是否可放置 | `boolean` | false | -| beforeDropMethod | 在放置节点之前执行的方法,返回 true 允许放置, false 可阻止放置 | `(dragKey: string \| number, dropKey: string \| number, hoverPart: 'before' \| 'body' \| 'after') => boolean` | `() => true` | -| ignoreMode | 忽略模式,指定 `getCheckedNodes`, `getCheckedKeys` 与 `v-model` 默认要忽略的部分 | `'none' \| 'parents' \| 'children'` | 'none' | -| autoLoad | 异步加载初始化时是否自动加载根节点 | `boolean` | true | -| load | 异步加载方法 | `(node: null \| TreeNode, resolve: Function, reject: Function) => any` | 无 | -| render | 节点渲染 render 函数 | `(h: CreateElement, node: TreeNode) => VNode` | 无 | -| filterMethod | 节点过滤方法 | `(keyword: string, node: TreeNode) => boolean` | 无 | -| expandOnFilter `2.1.0` | 过滤时是否展开所有可见节点 | `boolean` | true | -| unselectOnClick `2.1.0` | 点击已选中节点是否取消选中 | `boolean` | true | -| loading | 是否显示 loading 图标 | `boolean` | false | -| nodeClassName | 节点根元素的 class ,传入函数以对每个节点定制 class | `string \| object \| Array \| (node: TreeNode) => string \| object \| Array` | 无 | -| showLine `4.0.0` | 是否显示连接线,可指定连接线的宽度、颜色、实线、虚线,以及是否有折线 | `boolean \| { width?: number, type?: 'dashed' \| 'solid', color?: string, polyline?: boolean }` | 无,如果传入的非 boolean,则默认为 `{ width: 1, type: 'solid', color: '#D3D3D3', polyline: false }` | -| animation `4.0.0` | 是否启用过渡动画,目前仅控制展开收起 | `boolean` | 无 | -| nodeMinHeight | 根据节点最小高度计算数据总高度 | `number` | 30 | -| nodeIndent | 子节点缩进 | `number` | 20 | -| renderNodeAmount | 渲染节点数量,可见节点数大于此值且高度超过(容器可视高度能容纳节点数 + bufferNodeAmount)则不会渲染所有可见节点 | `number` | 100 | -| bufferNodeAmount | 当滚动到视野外的节点个数大于此值时刷新渲染节点 | `number` | 20 | +| Prop | Description | Type | Default Value | +| :------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------- | +| value | Selected or checked value. Supports `v-model`. `value` will be a string or number in single select mode; a `separator` separated string or an array in multiple select mode. Multiple select mode takes the priority | `string \| number \| Array` | None | +| data | Tree data. It's recommended to use `setData` method instead of props when the data amount is large | `object[]` | [] | +| unloadDataList | The list for querying node title of not loaded but selected nodes. The format is the same as `data` | `object[]` | [] | +| showUnloadCheckedNodes | Whether to show checked nodes that are not loaded after filter | `boolean` | true | +| emptyText | No data text | `string` | '暂无数据' | +| titleField | Node title field | `string` | 'title' | +| keyField | Node unique key field | `string` | 'id' | +| separator | Separator of `value` in multiple select mode | `string` | ',' | +| checkable | Enable multiple select | `boolean` | false | +| selectable | Enable single select | `boolean` | false | +| filteredNodeCheckable | Whether the filtered nodes can be checked | `boolean` | false | +| cascade | Whether parent nodes and child nodes are cascaded | `boolean` | true | +| enableLeafOnly | Whether to enable leaf nodes only. Effective when 'in multiple select mode and cascade is false' or 'in single select mode' | `boolean` | false | +| disableAll | Whether to disable all nodes | `boolean` | false | +| defaultExpandAll | Whether to expand all nodes by default | `boolean` | false | +| defaultExpandedKeys `Deprecated` | Default expanded keys | `Array` | [] | +| expandedKeys `2.2.0` | Expanded node keys. The component will react to the changes of this prop | `Array` | [] | +| draggable | Whether nodes can be dragged | `boolean` | false | +| droppable | Whether nodes can be dropped | `boolean` | false | +| beforeDropMethod | This method will be invoked before node drop. Return `true` to allow dropping. Return `false` to prevent from dropping | `(dragKey: string \| number, dropKey: string \| number, hoverPart: 'before' \| 'body' \| 'after') => boolean` | `() => true` | +| ignoreMode | Specify the nodes to ignore in `getCheckedNodes`, `getCheckedKeys` and `v-model` | `'none' \| 'parents' \| 'children'` | 'none' | +| autoLoad | Whether to auto load root nodes when init | `boolean` | true | +| load | async load method | `(node: null \| TreeNode, resolve: Function, reject: Function) => any` | None | +| render | Node render function | `(h: CreateElement, node: TreeNode) => VNode` | None | +| filterMethod | Node filter method | `(keyword: string, node: TreeNode) => boolean` | None | +| expandOnFilter `2.1.0` | Whether to expand all visible nodes when filter | `boolean` | true | +| unselectOnClick `2.1.0` | Whether to cancel select when click on selected node | `boolean` | true | +| loading | Whether to show loading icon | `boolean` | false | +| nodeClassName | Class passed to the root element of the node. Pass a function to customize class for each node | `string \| object \| Array \| (node: TreeNode) => string \| object \| Array` | None | +| showLine `4.0.0` | Whether to show connecting lines. Pass object to specify line width, color, type and polyline | `boolean \| { width?: number, type?: 'dashed' \| 'solid', color?: string, polyline?: boolean }` | None. If not boolean, the default value is `{ width: 1, type: 'solid', color: '#D3D3D3', polyline: false }` | +| animation `4.0.0` | Whether to enable transition animation. This prop only controls expand/collapse animation currently | `boolean` | None | +| nodeMinHeight | Calculate data total height according to node min height | `number` | 30 | +| nodeIndent | Child node indent | `number` | 20 | +| renderNodeAmount | Node amount to render. Not all visible nodes will be rendered when they are more than this prop and the height is more than (node amount the container clientHeight can hold + bufferNodeAmount) | `number` | 100 | +| bufferNodeAmount | Refresh render nodes when scrolled node amount is more than this prop | `number` | 20 | ## VTree Events -注:从 `2.0.8` 起,事件中返回的节点信息都是包括 `_parent` 与 `children` 的完整节点信息(拖拽事件的 `dataTransfer` 除外)。 +Note: Since `2.0.8`, the node info returned in events contains the full node info including `_parent` and `children`(`dataTransfer` in drag events excluded). -| Event | Description | Return Value | -| :--------------- | :-------------------------- | :-------------------------------------------------------------------------- | -| input | 选中节点改变时触发 | 选中的节点 | -| expand | 展开/折叠时触发 | 节点信息 | -| check | 勾选时触发(多选) | 被勾选的节点信息 | -| uncheck | 取消勾选时触发(多选) | 被取消勾选的节点信息 | -| checked-change | 勾选/取消勾选时触发(多选) | 所有被勾选节点(数组) | -| select | 选中时触发(单选) | 被选中的节点信息 | -| unselect | 取消选中时触发(单选) | 被取消选中的节点信息 | -| selected-change | 选中/取消选中时触发(单选) | 被选中节点 | -| click | 点击节点时触发 | 节点信息, 鼠标事件 | -| node-dblclick | 双击节点时触发 | 节点信息, 鼠标事件 | -| node-right-click | 右击节点时触发 | 节点信息, 鼠标事件 | -| node-dragstart | 开始拖拽节点时触发 | 节点信息, 拖拽事件对象 | -| node-dragenter | dragenter 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | -| node-dragover | dragover 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | -| node-dragleave | dragleave 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | -| node-drop | 放置节点时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | +| Event | Description | Return Value | +| :--------------- | :---------------------------------------------- | :----------------------------------------------------------------------------------- | +| input | Triggers when selected or checked nodes changes | Selected or checked nodes | +| expand | Triggers when expand/collapse node | Node info | +| check | Triggers when check node | Checked node info | +| uncheck | Triggers when cancel check node | Cancel checked node info | +| checked-change | Triggers when checked nodes changes | All checked nodes (an array) | +| select | Triggers when select node | Selected node info | +| unselect | Triggers when cancel select node | Cancel selected node info | +| selected-change | Triggers when selected node changes | Selected node | +| click | Triggers when click node | Node info, mouse event | +| node-dblclick | Triggers when double click node | Node info, mouse event | +| node-right-click | Triggers when right click node | Node info, mouse event | +| node-dragstart | Triggers when start dragging node | Node info, drag event | +| node-dragenter | Triggers when dragenter | Node info, drag event, node part that triggers event `'before' \| 'body' \| 'after'` | +| node-dragover | Triggers when dragover | Node info, drag event, node part that triggers event `'before' \| 'body' \| 'after'` | +| node-dragleave | Triggers when dragleave | Node info, drag event, node part that triggers event `'before' \| 'body' \| 'after'` | +| node-drop | Triggers when drop node | Node info, drag event, node part that triggers event `'before' \| 'body' \| 'after'` | ## VTree Methods -| Method | Description | Params | Return Value | -| :--------------------- | :---------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------- | -| setData | 使用此方法重置树数据,可避免大量数据被 vue 监听 | `data: object[]`: 同 data Prop | `void` | -| setChecked | 设置多选选中/取消选中 | `key: string \| number`: 节点 key
`value: boolean`: 是否选中 | `void` | -| setCheckedKeys | 批量设置选中/取消选中 | `keys: Array`: 节点 key
`value: boolean`: 是否选中 | `void` | -| checkAll | 设置所有数据全选 | 无 | `void` | -| clearChecked | 清空选中 | 无 | `void` | -| setSelected | 设置单选选中/取消选中 | `key: string \| number`: 节点 key
`value: boolean`: 是否选中 | `void` | -| setExpand | 设置展开/折叠 | `key: string \| number`: 节点 key
`value: boolean`: 是否展开
`expandParent: boolean = true`: 如果是展开是否同时展开父节点 `2.0.6` | `void` | -| setExpandKeys | 批量展开/折叠 | `keys: Array`: 节点 key
`value: boolean`: 是否展开 | `void` | -| setExpandAll | 设置全部展开/折叠 | `value: boolean`: 是否展开 | `void` | -| getCheckedNodes | 获取多选选中节点 | `ignoreMode: 'none' \| 'parents' \| 'children'`: 需要忽略的部分,默认为 ignoreMode Prop | `TreeNode[]` | -| getCheckedKeys | 获取多选选中节点 key | `ignoreMode: 'none' \| 'parents' \| 'children'`: 需要忽略的部分,默认为 ignoreMode Prop | `Array` | -| getIndeterminateNodes | 获取半选状态的节点 | 无 | `TreeNode[]` | -| getSelectedNode | 获取单选选中节点 | 无 | `TreeNode \| null` | -| getSelectedKey | 获取单选选中节点 key | 无 | `TreeNode \| null` | -| getExpandNodes | 获取展开的节点 | 无 | `TreeNode[]` | -| getExpandKeys | 获取展开的节点 key | 无 | `TreeNode[]` | -| getCurrentVisibleNodes | 获取当前可见的节点 | 无 | `TreeNode[]` | -| getNode | 根据 key 获取节点 | `key: string \| number`: 节点 key | `TreeNode \| null` | -| getTreeData | 获取树形结构的节点数据 | 无 | `TreeNode[]` | -| getFlatData | 获取扁平化后的节点数据 | 无 | `TreeNode[]` | -| getNodesCount | 获取节点总数量 | 无 | `number` | -| insertBefore | 在参照节点前插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`referenceKey: string \| number`: 参照节点 key | `TreeNode \| null` 返回插入的节点 | -| insertAfter | 在参照节点后插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`referenceKey: string \| number`: 参照节点 key | `TreeNode \| null` 返回插入的节点 | -| append | 在父节点第一层子节点的末尾插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`parentKey: string \| number`: 父节点 key | `TreeNode \| null` 返回插入的节点 | -| prepend | 在父节点第一层子节点的开头插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`parentKey: string \| number`: 父节点 key | `TreeNode \| null` 返回插入的节点 | -| remove | 删除节点 | `removedKey: string \| number`: 要删除的节点 key | `TreeNode \| null` 返回删除的节点 | -| filter | 过滤节点 | `keyword: string`: 过滤关键词
`filterMethod: (keyword: string, node: TreeNode) => boolean`: 过滤方法,默认为 filterMethod Prop ,如果没有传 filterMethod Prop 则为搜索 title 字段的一个内置方法 | `void` | -| showCheckedNodes | 展示已选节点 | `showUnloadCheckedNodes: boolean`: 是否显示未加载的选中节点,默认为 Prop 传入的值 | `void` | -| loadRootNodes | 从远程加载根节点 | 无 | `Promise` | -| scrollTo | 滚动到指定节点位置 | `key: string \| number`: 节点 key
`verticalPosition: 'top' \| 'center' \| 'bottom' \| number`: 滚动的垂直位置 | `void` | +| Method | Description | Params | Return Value | +| :--------------------- | :------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------- | +| setData | Set tree data to avoid large amount data being proxied by Vue | `data: object[]`: The same as data prop | `void` | +| setChecked | Set multiple select checked/not checked | `key: string \| number`: node key
`value: boolean`: is checked | `void` | +| setCheckedKeys | Batch set multiple select checked/not checked | `keys: Array`: node key
`value: boolean`: is checked | `void` | +| checkAll | Check all nodes | None | `void` | +| clearChecked | Clear checked nodes | None | `void` | +| setSelected | Set single select selected/not selected | `key: string \| number`: node key
`value: boolean`: is selected | `void` | +| setExpand | Set node expand/collapse | `key: string \| number`: node key
`value: boolean`: is expanded
`expandParent: boolean = true`: whether to expand parent nodes `2.0.6` | `void` | +| setExpandKeys | Batch set node expand/collapse | `keys: Array`: node key
`value: boolean`: is expanded | `void` | +| setExpandAll | Set expand/collapse all | `value: boolean`: is expanded | `void` | +| getCheckedNodes | Get multiple select checked nodes | `ignoreMode: 'none' \| 'parents' \| 'children'`: ignore part, default value is ignoreMode prop | `TreeNode[]` | +| getCheckedKeys | Get multiple select checked node keys | `ignoreMode: 'none' \| 'parents' \| 'children'`: ignore part, default value is ignoreMode prop | `Array` | +| getIndeterminateNodes | Get half checked nodes | None | `TreeNode[]` | +| getSelectedNode | Get single selected node | None | `TreeNode \| null` | +| getSelectedKey | Get single selected node key | None | `TreeNode \| null` | +| getExpandNodes | Get expanded nodes | None | `TreeNode[]` | +| getExpandKeys | Get expanded node keys | None | `TreeNode[]` | +| getCurrentVisibleNodes | Get current visible nodes | None | `TreeNode[]` | +| getNode | Get node by key | `key: string \| number`: node key | `TreeNode \| null` | +| getTreeData | Get tree format node data | None | `TreeNode[]` | +| getFlatData | Get flattened tree data | None | `TreeNode[]` | +| getNodesCount | Get total node count | None | `number` | +| insertBefore | Insert a node before reference node | `insertedNode`: node key or single node data
`referenceKey: string \| number`: reference node key | `TreeNode \| null` Returns inserted node | +| insertAfter | Insert a node after reference node | `insertedNode`: node key or single node data
`referenceKey: string \| number`: reference node key | `TreeNode \| null` Returns inserted node | +| append | Append a node to the first child layer of parent node | `insertedNode`: node key or single node data
`parentKey: string \| number`: parent node key | `TreeNode \| null` Returns inserted node | +| prepend | Prepend a node to the first child layer of parent node | `insertedNode`: node key or single node data
`parentKey: string \| number`: parent node key | `TreeNode \| null` Returns inserted node | +| remove | Remove node | `removedKey: string \| number`: node key to remove | `TreeNode \| null` Returns removed node | +| filter | Filter nodes | `keyword: string`: filter keyword
`filterMethod: (keyword: string, node: TreeNode) => boolean`: filter method, default to filterMethod prop. if filterMethod prop is not present, it's an internal method that searches node title | `void` | +| showCheckedNodes | Show checked nodes | `showUnloadCheckedNodes: boolean`: whether to show checked nodes that are not loaded, default to prop value | `void` | +| loadRootNodes | Load root nodes from remote | None | `Promise` | +| scrollTo | Scroll to specific node position | `key: string \| number`: node key
`verticalPosition: 'top' \| 'center' \| 'bottom' \| number`: vertical position of scrolling | `void` | ## VTree Slots -| Name | Description | -| :----------- | :-------------------------------------------- | -| empty | 暂无数据 | -| loading | 加载中显示的图标 | -| node `4.0.0` | 自定义节点,slotProps 为 `{ node: TreeNode }` | +| Name | Description | +| :----------- | :--------------------------------------------- | +| empty | No data | +| loading | Icon displayed when loading | +| node `4.0.0` | Custom node, slotProps is `{ node: TreeNode }` | ## VTree Data Fields -Note: It's better not to override the fields starting with '`_`' to avoid the impact on the internal logic +Note: It's better not to override the fields starting with '`_`' to avoid impact on the internal logic -| Field | Description | -| :-------------- | :------------------------------------------------------------------------------ | -| id | 默认以 'id' 作为 key 字段,也可以通过 `keyField` Prop 指定其他字段作为 key 字段 | -| title | 默认显示的名称,可通过 `titleField` Prop 指定其他字段作为 title 字段 | -| checked | 多选模式下是否勾选 | -| selected | 单选模式下是否选中 | -| indeterminate | 多选模式下是否半选状态 | -| disabled | 是否禁用 | -| expand | 父节点有效,节点展开状态 | -| visible | 是否可见 | -| \_filterVisible | 过滤后是否可见,如果为 false 则在其他可见情况下也是不可见的 | -| \_parent | 父节点 | -| children | 子节点数组 | -| isLeaf | 标记节点是否为叶子节点 | -| \_level | 节点层级,默认从 0 开始 | -| \_loading | 节点是否正在加载 | -| \_loaded | 节点是否已经加载过,异步加载下有效 | +| Field | Description | +| :-------------- | :------------------------------------------------------------------------------------------ | +| id | Default key field. You can specify other field as key by setting `keyField` prop | +| title | Default display name. You can specify other field as title by setting `titleField` prop | +| checked | Whether node is checked in multiple select mode | +| selected | Whether node is selected in single select mode | +| indeterminate | Whether node is half checked in multiple select mode | +| disabled | Whether node is disabled | +| expand | Effective to parent nodes. Whether node is expanded | +| visible | Whether node is visible | +| \_filterVisible | Whether is visible after filter. If it's false, the node is not visible in other situations | +| \_parent | Parent node | +| children | Child node list | +| isLeaf | Whether is leaf node | +| \_level | Node level, starting from 0 | +| \_loading | Whether is loading node | +| \_loaded | Whether node is loaded. Effective when async load | diff --git a/site/en/guide/migration.md b/site/en/guide/migration.md index e1a9b9c..fd35f98 100644 --- a/site/en/guide/migration.md +++ b/site/en/guide/migration.md @@ -14,8 +14,8 @@ Vue support info: To migrate from `@wsfe/ctree` or `@wsfe/vue-tree` 3.x to `@wsfe/vue-tree` 4.x, follow these steps: -1. Update all Less variables and CSS related class prefix from ctree to vtree -2. Change the prefix of exported modules from C to V +1. Update all Less variables and CSS related class prefix from `ctree` to `vtree` +2. Change the prefix of exported modules from `C` to `V` ```typescript import CTree, { CTreeSearch, CTreeDrop } from '@wsfe/ctree' // [!code --] diff --git a/site/guide/migration.md b/site/guide/migration.md index 680bc47..a868fb2 100644 --- a/site/guide/migration.md +++ b/site/guide/migration.md @@ -14,8 +14,8 @@ 从 `@wsfe/ctree` 或者 `@wsfe/vue-tree` 3.x 迁移到 `@wsfe/vue-tree` 4.x 需按如下步骤修改: -1. 所有 Less 变量与 CSS 相关 class 前缀从 ctree 改为 vtree -2. 导出的包前缀从 C 改为 V,例如: +1. 所有 Less 变量与 CSS 相关 class 前缀从 `ctree` 改为 `vtree` +2. 导出的包前缀从 `C` 改为 `V`,例如: ```typescript import CTree, { CTreeSearch, CTreeDrop } from '@wsfe/ctree' // [!code --] From 5569d04d2d9e6e8d2cbe625594edb0c6eae5048f Mon Sep 17 00:00:00 2001 From: ChuChencheng Date: Wed, 3 Jul 2024 03:00:04 +0800 Subject: [PATCH 3/3] feat: finish doc --- .github/workflows/deploy.yml | 64 ++++ README.md | 304 +----------------- README_EN.md | 9 + package.json | 2 + pnpm-lock.yaml | 14 + site/.vitepress/components/Playground.vue | 129 +++++++- site/.vitepress/components/PlaygroundLink.vue | 4 +- site/.vitepress/components/VersionSelect.vue | 115 +++++++ site/.vitepress/config.mts | 1 + site/.vitepress/theme/index.ts | 13 +- site/package.json | 6 +- site/playground.md | 6 +- site/pnpm-lock.yaml | 23 -- site/vite.config.ts | 9 + 14 files changed, 348 insertions(+), 351 deletions(-) create mode 100644 .github/workflows/deploy.yml create mode 100644 README_EN.md create mode 100644 site/.vitepress/components/VersionSelect.vue delete mode 100644 site/pnpm-lock.yaml create mode 100644 site/vite.config.ts diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..8d72940 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,64 @@ +# 构建 VitePress 站点并将其部署到 GitHub Pages 的示例工作流程 +# +name: Deploy VitePress site to Pages + +on: + # 在针对 `main` 分支的推送上运行。如果你 + # 使用 `master` 分支作为默认分支,请将其更改为 `master` + push: + branches: [dev] + + # 允许你从 Actions 选项卡手动运行此工作流程 + workflow_dispatch: + +# 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# 只允许同时进行一次部署,跳过正在运行和最新队列之间的运行队列 +# 但是,不要取消正在进行的运行,因为我们希望允许这些生产部署完成 +concurrency: + group: pages + cancel-in-progress: false + +jobs: + # 构建工作 + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # 如果未启用 lastUpdated,则不需要 + - uses: pnpm/action-setup@v3 # 如果使用 pnpm,请取消注释 + # - uses: oven-sh/setup-bun@v1 # 如果使用 Bun,请取消注释 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm # 或 pnpm / yarn + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: pnpm install # 或 pnpm install / yarn install / bun install + - name: Build with VitePress + run: pnpm docs:build # 或 pnpm docs:build / yarn docs:build / bun run docs:build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: site/.vitepress/dist + + # 部署工作 + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/README.md b/README.md index 2f0b573..fd9366f 100644 --- a/README.md +++ b/README.md @@ -1,305 +1,9 @@ # Vue-Tree 4.x -一款高性能 vue 虚拟树控件,支持搜索,定位,拖拽等。该控件是在公司业务的基础上不断打磨出来的,提供了十分丰富强大的 API,几乎能够满足你对树控件的所有需求。 +简体中文 | [English](https://github.com/wsfe/vue-tree/blob/dev/README_EN.md) -> 这是原先 [ctree](https://github.com/wsfe/vue-tree/tree/2.x) 的升级版本 -> 新版改变了包的名称和部分 export 模块名称。 +[接口文档与在线示例](https://wsfe.github.io/vue-tree/) -## **注意** +一款高性能 Vue3 虚拟树控件,支持搜索,定位,拖拽等。该控件是在公司业务的基础上不断打磨出来的,提供了十分丰富强大的 API,几乎能够满足你对树控件的所有需求。 -`@wsfe/vue-tree` 3.x 尝试使用 `vue-demi` 包使组件在 Vue 2/3 都通用。但遗憾的是 `vue-demi` 并不能完美使 Vue3 组件兼容 Vue2。`@wsfe/vue-tree` 4.x 将仅支持 Vue3 - -因此,建议 Vue2 用户使用 `@wsfe/ctree` 包 - -## 从旧版迁移 - -从 `@wsfe/ctree` 或者 `@wsfe/vue-tree` 3.x 迁移到 `@wsfe/vue-tree` 4.x 需按如下步骤修改: - -1. 所有 Less 变量与 CSS 相关 class 前缀从 `ctree` 改为 `vtree` -2. 导出的包前缀从 `C` 改为 `V`,例如: - -```diff -- import CTree, { CTreeSearch, CTreeDrop } from '@wsfe/ctree' -+ import VTree, { VTreeSearch, VTreeDrop } from '@wsfe/vue-tree' -``` - -## 案例 - -[在线 demo](https://wsfe.github.io/vue-tree/) - -## 安装 - -### yarn 安装方式 - -```bash -yarn add @wsfe/vue-tree -``` - -### npm 安装方式 - -```bash -npm install @wsfe/vue-tree -``` - -### 样式引入 - -直接引入 css - -```less -@import '~@wsfe/vue-tree/style.css'; -``` - -引入 less 以便于变量覆盖 - -```less -@import '~@wsfe/vue-tree/src/styles/index.less'; -``` - -### 使用方式 - -```typescript -// 大家可以根据需要是否引入VTreeNode, VTreeSearch, VTreeDrop -import VTree, { VTreeNode, VTreeSearch, VTreeDrop } from '@wsfe/vue-tree' -import '@wsfe/vue-tree/style.css' -``` - -# 接口文档 - -## VTree API - -### VTree Props - -| 属性 | 说明 | 类型 | 默认值 | -| :------------------------------- | :------------------------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- | -| value | 选中的值,可用 v-model ;单选为字符串或数字,多选为 `separator` 分隔的字符串或数组,优先多选 | `string \| number \| Array` | 无 | -| data | 传入的树数据。数据量大时,不建议通过 props 传入数据,建议用 `setData` 方法代替 | `object[]` | [] | -| unloadDataList | 供未加载且选中节点查询 title 字段值用的列表,格式与 `data` 一致即可 | `object[]` | [] | -| showUnloadCheckedNodes | 过滤已选时是否在列表后面展示未加载的已选节点 | `boolean` | true | -| emptyText | 数据为空时显示的文本 | `string` | '暂无数据' | -| titleField | 节点标题字段 | `string` | 'title' | -| keyField | 节点唯一标识字段 | `string` | 'id' | -| separator | 多选模式下 value 分隔符 | `string` | ',' | -| checkable | 是否可多选 | `boolean` | false | -| selectable | 是否可单选 | `boolean` | false | -| filteredNodeCheckable | 是否可勾选被过滤节点 | `boolean` | false | -| cascade | 父子节点是否关联 | `boolean` | true | -| enableLeafOnly | 是否只启用子节点,当 `多选且父子不关联` 或 `单选` 时有效 | `boolean` | false | -| disableAll | 是否禁用所有节点 | `boolean` | false | -| defaultExpandAll | 是否默认展开所有节点 | `boolean` | false | -| defaultExpandedKeys `Deprecated` | 默认展开的节点 key | `Array` | [] | -| expandedKeys `2.2.0` | 展开的节点 key ,组件内部将会响应此 Prop 的变化 | `Array` | [] | -| draggable | 是否可拖拽 | `boolean` | false | -| droppable | 是否可放置 | `boolean` | false | -| beforeDropMethod | 在放置节点之前执行的方法,返回 true 允许放置, false 可阻止放置 | `(dragKey: string \| number, dropKey: string \| number, hoverPart: 'before' \| 'body' \| 'after') => boolean` | `() => true` | -| ignoreMode | 忽略模式,指定 `getCheckedNodes`, `getCheckedKeys` 与 `v-model` 默认要忽略的部分 | `'none' \| 'parents' \| 'children'` | 'none' | -| autoLoad | 异步加载初始化时是否自动加载根节点 | `boolean` | true | -| load | 异步加载方法 | `(node: null \| TreeNode, resolve: Function, reject: Function) => any` | 无 | -| render | 节点渲染 render 函数 | `(h: CreateElement, node: TreeNode) => VNode` | 无 | -| filterMethod | 节点过滤方法 | `(keyword: string, node: TreeNode) => boolean` | 无 | -| expandOnFilter `2.1.0` | 过滤时是否展开所有可见节点 | `boolean` | true | -| unselectOnClick `2.1.0` | 点击已选中节点是否取消选中 | `boolean` | true | -| loading | 是否显示 loading 图标 | `boolean` | false | -| nodeClassName | 节点根元素的 class ,传入函数以对每个节点定制 class | `string \| object \| Array \| (node: TreeNode) => string \| object \| Array` | 无 | -| showLine `4.0.0` | 是否显示连接线,可指定连接线的宽度、颜色、实线、虚线,以及是否有折线 | `boolean \| { width?: number, type?: 'dashed' \| 'solid', color?: string, polyline?: boolean }` | 无,如果传入的非 boolean,则默认为 `{ width: 1, type: 'solid', color: '#D3D3D3', polyline: false }` | -| animation `4.0.0` | 是否启用过渡动画,目前仅控制展开收起 | `boolean` | 无 | -| nodeMinHeight | 根据节点最小高度计算数据总高度 | `number` | 30 | -| nodeIndent | 子节点缩进 | `number` | 20 | -| renderNodeAmount | 渲染节点数量,可见节点数大于此值且高度超过(容器可视高度能容纳节点数 + bufferNodeAmount)则不会渲染所有可见节点 | `number` | 100 | -| bufferNodeAmount | 当滚动到视野外的节点个数大于此值时刷新渲染节点 | `number` | 20 | - -### VTree Events - -注:从 `2.0.8` 起,事件中返回的节点信息都是包括 `_parent` 与 `children` 的完整节点信息(拖拽事件的 `dataTransfer` 除外)。 - -| 事件名 | 说明 | 返回值 | -| :--------------- | :-------------------------- | :-------------------------------------------------------------------------- | -| input | 选中节点改变时触发 | 选中的节点 | -| expand | 展开/折叠时触发 | 节点信息 | -| check | 勾选时触发(多选) | 被勾选的节点信息 | -| uncheck | 取消勾选时触发(多选) | 被取消勾选的节点信息 | -| checked-change | 勾选/取消勾选时触发(多选) | 所有被勾选节点(数组) | -| select | 选中时触发(单选) | 被选中的节点信息 | -| unselect | 取消选中时触发(单选) | 被取消选中的节点信息 | -| selected-change | 选中/取消选中时触发(单选) | 被选中节点 | -| click | 点击节点时触发 | 节点信息, 鼠标事件 | -| node-dblclick | 双击节点时触发 | 节点信息, 鼠标事件 | -| node-right-click | 右击节点时触发 | 节点信息, 鼠标事件 | -| node-dragstart | 开始拖拽节点时触发 | 节点信息, 拖拽事件对象 | -| node-dragenter | dragenter 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | -| node-dragover | dragover 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | -| node-dragleave | dragleave 时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | -| node-drop | 放置节点时触发 | 节点信息 , 拖拽事件对象, 事件触发的节点部位 `'before' \| 'body' \| 'after'` | - -### VTree Methods - -| 方法 | 说明 | 参数 | 返回值 | -| :--------------------- | :---------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------- | -| setData | 使用此方法重置树数据,可避免大量数据被 vue 监听 | `data: object[]`: 同 data Prop | `void` | -| setChecked | 设置多选选中/取消选中 | `key: string \| number`: 节点 key
`value: boolean`: 是否选中 | `void` | -| setCheckedKeys | 批量设置选中/取消选中 | `keys: Array`: 节点 key
`value: boolean`: 是否选中 | `void` | -| checkAll | 设置所有数据全选 | 无 | `void` | -| clearChecked | 清空选中 | 无 | `void` | -| setSelected | 设置单选选中/取消选中 | `key: string \| number`: 节点 key
`value: boolean`: 是否选中 | `void` | -| setExpand | 设置展开/折叠 | `key: string \| number`: 节点 key
`value: boolean`: 是否展开
`expandParent: boolean = true`: 如果是展开是否同时展开父节点 `2.0.6` | `void` | -| setExpandKeys | 批量展开/折叠 | `keys: Array`: 节点 key
`value: boolean`: 是否展开 | `void` | -| setExpandAll | 设置全部展开/折叠 | `value: boolean`: 是否展开 | `void` | -| getCheckedNodes | 获取多选选中节点 | `ignoreMode: 'none' \| 'parents' \| 'children'`: 需要忽略的部分,默认为 ignoreMode Prop | `TreeNode[]` | -| getCheckedKeys | 获取多选选中节点 key | `ignoreMode: 'none' \| 'parents' \| 'children'`: 需要忽略的部分,默认为 ignoreMode Prop | `Array` | -| getIndeterminateNodes | 获取半选状态的节点 | 无 | `TreeNode[]` | -| getSelectedNode | 获取单选选中节点 | 无 | `TreeNode \| null` | -| getSelectedKey | 获取单选选中节点 key | 无 | `TreeNode \| null` | -| getExpandNodes | 获取展开的节点 | 无 | `TreeNode[]` | -| getExpandKeys | 获取展开的节点 key | 无 | `TreeNode[]` | -| getCurrentVisibleNodes | 获取当前可见的节点 | 无 | `TreeNode[]` | -| getNode | 根据 key 获取节点 | `key: string \| number`: 节点 key | `TreeNode \| null` | -| getTreeData | 获取树形结构的节点数据 | 无 | `TreeNode[]` | -| getFlatData | 获取扁平化后的节点数据 | 无 | `TreeNode[]` | -| getNodesCount | 获取节点总数量 | 无 | `number` | -| insertBefore | 在参照节点前插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`referenceKey: string \| number`: 参照节点 key | `TreeNode \| null` 返回插入的节点 | -| insertAfter | 在参照节点后插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`referenceKey: string \| number`: 参照节点 key | `TreeNode \| null` 返回插入的节点 | -| append | 在父节点第一层子节点的末尾插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`parentKey: string \| number`: 父节点 key | `TreeNode \| null` 返回插入的节点 | -| prepend | 在父节点第一层子节点的开头插入一个节点 | `insertedNode`: 节点 key 或者单个节点数据
`parentKey: string \| number`: 父节点 key | `TreeNode \| null` 返回插入的节点 | -| remove | 删除节点 | `removedKey: string \| number`: 要删除的节点 key | `TreeNode \| null` 返回删除的节点 | -| filter | 过滤节点 | `keyword: string`: 过滤关键词
`filterMethod: (keyword: string, node: TreeNode) => boolean`: 过滤方法,默认为 filterMethod Prop ,如果没有传 filterMethod Prop 则为搜索 title 字段的一个内置方法 | `void` | -| showCheckedNodes | 展示已选节点 | `showUnloadCheckedNodes: boolean`: 是否显示未加载的选中节点,默认为 Prop 传入的值 | `void` | -| loadRootNodes | 从远程加载根节点 | 无 | `Promise` | -| scrollTo | 滚动到指定节点位置 | `key: string \| number`: 节点 key
`verticalPosition: 'top' \| 'center' \| 'bottom' \| number`: 滚动的垂直位置 | `void` | - -### VTree Slots - -| 名称 | 说明 | -| :----------- | :-------------------------------------------- | -| empty | 暂无数据 | -| loading | 加载中显示的图标 | -| node `4.0.0` | 自定义节点,slotProps 为 `{ node: TreeNode }` | - -### VTree Data Fields - -注:以 '`_`' 开头的字段最好不要覆盖,以免影响内部处理逻辑 - -| 字段 | 说明 | -| :-------------- | :------------------------------------------------------------------------------ | -| id | 默认以 'id' 作为 key 字段,也可以通过 `keyField` Prop 指定其他字段作为 key 字段 | -| title | 默认显示的名称,可通过 `titleField` Prop 指定其他字段作为 title 字段 | -| checked | 多选模式下是否勾选 | -| selected | 单选模式下是否选中 | -| indeterminate | 多选模式下是否半选状态 | -| disabled | 是否禁用 | -| expand | 父节点有效,节点展开状态 | -| visible | 是否可见 | -| \_filterVisible | 过滤后是否可见,如果为 false 则在其他可见情况下也是不可见的 | -| \_parent | 父节点 | -| children | 子节点数组 | -| isLeaf | 标记节点是否为叶子节点 | -| \_level | 节点层级,默认从 0 开始 | -| \_loading | 节点是否正在加载 | -| \_loaded | 节点是否已经加载过,异步加载下有效 | - -## VTreeSearch API - -### VTreeSearch Props - -注:可在 `VTreeSearch` 上直接使用 `VTree` 的所有 Props - -| 属性 | 说明 | 类型 | 默认值 | -| :------------------- | :--------------------------------------------------------------------------------- | :------------------------------------------- | :----------- | -| searchPlaceholder | 搜索输入框的 placeholder | `string` | '搜索关键字' | -| showCheckAll | 是否显示全选复选框 | `boolean` | true | -| showCheckedButton | 是否显示已选按钮 | `boolean` | true | -| checkedButtonText | 已选按钮文字 | `string` | '已选' | -| showFooter | 是否显示底部信息 | `boolean` | true | -| searchMethod `2.0.2` | 如果传入此 Prop ,触发 `search` 事件后将会执行此方法,否则会执行组件内置的搜索方法 | `(keyword: string) => void \| Promise` | 无 | -| searchLength | 触发搜索的字符长度 | `number` | 1 | -| searchDisabled | 禁用搜索功能 | `boolean` | false | -| searchRemote | 是否远程搜索,传入 `searchMethod` 时无效 | `boolean` | false | -| searchDebounceTime | 搜索防抖时间,单位为毫秒 | `number` | 300 | - -### VTreeSearch Events - -注:可在 `VTreeSearch` 上直接监听 `VTree` 的所有 Events - -| 事件名 | 说明 | 返回值 | -| :----- | :----------------- | :----------- | -| search | 执行搜索操作时触发 | 搜索的关键字 | - -### VTreeSearch Methods - -注:可在 `VTreeSearch` 上直接调用 `VTree` 的所有 Methods - -| 方法 | 说明 | 参数 | 返回值 | -| :----------- | :------------- | :------------------------------------------------------- | :-------------- | -| clearKeyword | 清空关键字 | 无 | `void` | -| getKeyword | 获取搜索关键字 | 无 | `string` | -| search | 执行搜索 | `keyword: string`: 搜索的关键字,默认为内部 this.keyword | `Promise` | - -### VTreeSearch Slots - -注:可在 `VTreeSearch` 上直接传入 `VTree` 的所有 Slots - -| 名称 | 说明 | -| :----------- | :------------------------------------------------- | -| search-input | 搜索输入框,可通过此 slot 自行封装树搜索组件的行为 | -| actions | 操作按钮,可在搜索输入框后加入更多操作按钮 | -| footer | 底部信息 | - -## VTreeDrop API - -### VTreeDrop Props - -注:可在 `VTreeDrop` 上直接使用 `VTree` 和 `VTreeSearch` 的所有 Props - -| 属性 | 说明 | 类型 | 默认值 | -| :------------------------- | :------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- | :------------- | -| dropHeight | 下拉内容高度 | `number` | 300 | -| dropPlaceholder | 展示输入框 placeholder | `string` | 无 | -| dropDisabled | 是否禁用 | `boolean` | false | -| clearable | 允许清空 | `boolean` | false | -| placement | 下拉弹出框位置,注意!!不支持自动识别方向 | `'bottom-start' \| 'bottom-end' \| 'bottom' \| 'top-start' \| 'top-end' \| 'top'` | 'bottom-start' | -| transfer | 将下拉 DOM 转移到 body 中 | `boolean` | false | -| dropdownClassName | 在下拉框容器上额外添加的 class | `string \| string[]` | 无 | -| dropdownMinWidth `2.0.1` | 下拉框容器最小宽度,未指定则默认为展示输入框宽度。 适合 transfer 为 false 时使用 | `number` | 无 | -| dropdownWidthFixed `2.0.5` | 固定下拉框容器宽度,当内容超出最小宽度不会伸长,而是出现横向滚动条 | `boolean` | false | - -### VTreeDrop Events - -注:可在 `VTreeDrop` 上直接监听 `VTree` 和 `VTreeSearch` 的所有 Events - -| 事件名 | 说明 | 返回值 | -| :---------------------- | :--------------------- | :------------- | -| dropdown-visible-change | 下拉框出现或消失时触发 | 下拉框是否可见 | -| clear | 点击清空按钮时触发 | 无 | - -### VTreeDrop Methods - -注:可在 `VTreeDrop` 上直接调用 `VTree` 和 `VTreeSearch` 的所有 Methods - -### VTreeDrop Slots - -注:可在 `VTreeDrop` 上直接传入 `VTree` 和 `VTreeSearch` 的所有 Slots - -| 名称 | 说明 | -| :------ | :--------------------------------------------------- | -| 默认 | 展示输入框 | -| display | 展示输入框的展示文字,如果有默认 slot 则此 slot 无效 | -| clear | 替换清空图标,如果有默认 slot 则此 slot 无效 | - -默认 slot 与 display slot 的 Slot Props `2.3.0` : - -```typescript -/** 展示 slot 的 props */ -slotProps: { - /** 多选选中的节点 */ - checkedNodes: [] as TreeNode[], - - /** 多选选中的节点 key */ - checkedKeys: [] as Array, - - /** 单选选中的节点 */ - selectedNode: null as TreeNode | null, - - /** 单选选中的节点 key */ - selectedKey: null as string | number | null, -}, -``` - -**注意**: `checkedNodes` 与 `selectedNode` 只包含已加载的节点,如果设置了选中的值(比如设置了 `value` Prop),但没有设置树的数据,则这两个字段内容将为空;而 `checkedKeys` 与 `selectedKey` 则会包含未加载的选中节点 key 。 +Vue2 版本树组件请使用 [`@wsfe/ctree`](https://github.com/wsfe/vue-tree/tree/2.x) diff --git a/README_EN.md b/README_EN.md new file mode 100644 index 0000000..cbdf2a9 --- /dev/null +++ b/README_EN.md @@ -0,0 +1,9 @@ +# Vue-Tree 4.x + +[简体中文](https://github.com/wsfe/vue-tree) | English + +[API Document & Online Demo](https://wsfe.github.io/vue-tree/en/) + +A high performance Vue3 tree component optimized using virtual list. It supports searching, node locating, drag-and-drop, etc. This component is built based on business, providing rich and powerful APIs which can meet your various needs for a tree component. + +For Vue2 users, please use [`@wsfe/ctree`](https://github.com/wsfe/vue-tree/tree/2.x) (Chinese doc only) diff --git a/package.json b/package.json index 7ce4241..1e0297e 100644 --- a/package.json +++ b/package.json @@ -64,8 +64,10 @@ "@faker-js/faker": "^8.4.1", "@vitejs/plugin-vue": "^5.0.5", "@vue/babel-preset-app": "^5.0.8", + "@vue/repl": "^4.3.0", "@vue/test-utils": "^2.4.6", "@vue/vue3-jest": "^29.2.6", + "@wsfe/vue-tree": "^4.0.1", "autoprefixer": "^10.4.19", "happy-dom": "^14.12.0", "less": "^4.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 15b512e..776b06c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,12 +20,18 @@ devDependencies: '@vue/babel-preset-app': specifier: ^5.0.8 version: 5.0.8(@babel/core@7.24.7)(vue@3.4.30) + '@vue/repl': + specifier: ^4.3.0 + version: 4.3.0 '@vue/test-utils': specifier: ^2.4.6 version: 2.4.6 '@vue/vue3-jest': specifier: ^29.2.6 version: 29.2.6(@babel/core@7.24.7)(babel-jest@29.7.0)(jest@29.7.0)(typescript@5.4.5)(vue@3.4.30) + '@wsfe/vue-tree': + specifier: ^4.0.1 + version: 4.0.1 autoprefixer: specifier: ^10.4.19 version: 10.4.19(postcss@8.4.38) @@ -2712,6 +2718,10 @@ packages: '@vue/shared': 3.4.30 dev: true + /@vue/repl@4.3.0: + resolution: {integrity: sha512-TTo3Ie75YMpJ1LGWTsgq1jn/wCI4W++9sefkL0Vc7PpRv7s7+rPxUNgniyqaf1+yZEvC0oVNI/2Jiof42ihhpA==} + dev: true + /@vue/runtime-core@3.4.30: resolution: {integrity: sha512-qaFEbnNpGz+tlnkaualomogzN8vBLkgzK55uuWjYXbYn039eOBZrWxyXWq/7qh9Bz2FPifZqGjVDl/FXiq9L2g==} dependencies: @@ -2852,6 +2862,10 @@ packages: - vue dev: true + /@wsfe/vue-tree@4.0.1: + resolution: {integrity: sha512-B3a1bddMfvv2Nzjsw12EOID3ccvvPDiT1GSLY/LFP/S36EvvmMbR5giIj6yhigSpTYNF4j6ORiowMxpwM1Rt6w==} + dev: true + /abbrev@2.0.0: resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} diff --git a/site/.vitepress/components/Playground.vue b/site/.vitepress/components/Playground.vue index 52c0ff7..58a068f 100644 --- a/site/.vitepress/components/Playground.vue +++ b/site/.vitepress/components/Playground.vue @@ -1,32 +1,135 @@ diff --git a/site/.vitepress/components/PlaygroundLink.vue b/site/.vitepress/components/PlaygroundLink.vue index 5adda08..7c56621 100644 --- a/site/.vitepress/components/PlaygroundLink.vue +++ b/site/.vitepress/components/PlaygroundLink.vue @@ -1,10 +1,10 @@ + + diff --git a/site/.vitepress/config.mts b/site/.vitepress/config.mts index 1c8262f..bf58340 100644 --- a/site/.vitepress/config.mts +++ b/site/.vitepress/config.mts @@ -4,6 +4,7 @@ import en from './en.mjs' // https://vitepress.dev/reference/site-config export default defineConfig({ + base: '/vue-tree/', title: "Vue Tree", description: "Virtual list optimized Vue tree component", appearance: false, diff --git a/site/.vitepress/theme/index.ts b/site/.vitepress/theme/index.ts index cec9887..aa4a439 100644 --- a/site/.vitepress/theme/index.ts +++ b/site/.vitepress/theme/index.ts @@ -9,18 +9,17 @@ const codeDemoComponents = import.meta.glob('../code/*.vue') export default { extends: DefaultTheme, - enhanceApp({ app }) { + async enhanceApp({ app }) { // 注册自定义全局组件 app.component('CodeDemo', CodeDemo) app.component('PlaygroundLink', PlaygroundLink) for (const path in codeDemoComponents) { - codeDemoComponents[path]().then((component) => { - const componentName = path.match(/^(?:.*\/)?(.+)\.vue$/)?.[1] - if (componentName && component?.default) { - app.component(componentName, component.default) - } - }) + const component = await codeDemoComponents[path]() + const componentName = path.match(/^(?:.*\/)?(.+)\.vue$/)?.[1] + if (componentName && component?.default) { + app.component(componentName, component.default) + } } } } satisfies Theme diff --git a/site/package.json b/site/package.json index 0afed5f..1ce9c8c 100644 --- a/site/package.json +++ b/site/package.json @@ -1,9 +1,5 @@ { "name": "@wsfe/vue-tree-site", "version": "0.1.0", - "type": "module", - "dependencies": { - "@vue/repl": "^4.2.1", - "@wsfe/vue-tree": "^4.0.0" - } + "type": "module" } \ No newline at end of file diff --git a/site/playground.md b/site/playground.md index 2af4ceb..2b736a8 100644 --- a/site/playground.md +++ b/site/playground.md @@ -7,5 +7,9 @@ sidebar: false diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml deleted file mode 100644 index 688c535..0000000 --- a/site/pnpm-lock.yaml +++ /dev/null @@ -1,23 +0,0 @@ -lockfileVersion: '6.1' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -dependencies: - '@vue/repl': - specifier: ^4.2.1 - version: 4.2.1 - '@wsfe/vue-tree': - specifier: ^4.0.0 - version: 4.0.0 - -packages: - - /@vue/repl@4.2.1: - resolution: {integrity: sha512-kPpoAp0hQ1sKIGXEHtVdtdh2BgL97SAizEvCqRDB3LmgIYCPbzInwd4mqYkHstAhJPmkNslLd3rwfceMwzwinQ==} - dev: false - - /@wsfe/vue-tree@4.0.0: - resolution: {integrity: sha512-gFHQmvHCky5LHs4MinBc+kZsInf/sU8GFdyy4QZvCrII5yQfjkEF4TpSYG1SZFnPAN2ZOvFvJq5aDlT3X8rQmA==} - dev: false diff --git a/site/vite.config.ts b/site/vite.config.ts new file mode 100644 index 0000000..b22ab45 --- /dev/null +++ b/site/vite.config.ts @@ -0,0 +1,9 @@ +import { defineConfig, UserConfig } from 'vite' + +export default defineConfig((): UserConfig => { + return { + ssr: { + noExternal: ['@vue/repl'], + }, + } +})