feat: add echarts

This commit is contained in:
2026-02-02 20:14:48 +08:00
parent 8311456a9e
commit e6fbcff21a
8 changed files with 194 additions and 5 deletions

View File

@@ -10,6 +10,7 @@
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"daisyui": "^5.0.50", "daisyui": "^5.0.50",
"echarts": "^6.0.0",
"element-plus": "^2.13.2", "element-plus": "^2.13.2",
"lucide-vue-next": "^0.563.0", "lucide-vue-next": "^0.563.0",
"motion-v": "^1.6.1", "motion-v": "^1.6.1",
@@ -19,6 +20,7 @@
"reka-ui": "^2.8.0", "reka-ui": "^2.8.0",
"tailwind-merge": "^3.4.0", "tailwind-merge": "^3.4.0",
"vue": "^3.5.17", "vue": "^3.5.17",
"vue-echarts": "^8.0.1",
"vue-i18n": "11", "vue-i18n": "11",
"vue-router": "^4.5.1", "vue-router": "^4.5.1",
}, },
@@ -568,6 +570,8 @@
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"echarts": ["echarts@6.0.0", "", { "dependencies": { "tslib": "2.3.0", "zrender": "6.0.0" } }, "sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ=="],
"electron-to-chromium": ["electron-to-chromium@1.5.217", "", {}, "sha512-Pludfu5iBxp9XzNl0qq2G87hdD17ZV7h5T4n6rQXDi3nCyloBV3jreE9+8GC6g4X/5yxqVgXEURpcLtM0WS4jA=="], "electron-to-chromium": ["electron-to-chromium@1.5.217", "", {}, "sha512-Pludfu5iBxp9XzNl0qq2G87hdD17ZV7h5T4n6rQXDi3nCyloBV3jreE9+8GC6g4X/5yxqVgXEURpcLtM0WS4jA=="],
"element-plus": ["element-plus@2.13.2", "", { "dependencies": { "@ctrl/tinycolor": "^3.4.1", "@element-plus/icons-vue": "^2.3.2", "@floating-ui/dom": "^1.0.1", "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", "@types/lodash": "^4.17.20", "@types/lodash-es": "^4.17.12", "@vueuse/core": "^10.11.0", "async-validator": "^4.2.5", "dayjs": "^1.11.19", "lodash": "^4.17.23", "lodash-es": "^4.17.23", "lodash-unified": "^1.0.3", "memoize-one": "^6.0.0", "normalize-wheel-es": "^1.2.0" }, "peerDependencies": { "vue": "^3.3.0" } }, "sha512-Zjzm1NnFXGhV4LYZ6Ze9skPlYi2B4KAmN18FL63A3PZcjhDfroHwhtM6RE8BonlOPHXUnPQynH0BgaoEfvhrGw=="], "element-plus": ["element-plus@2.13.2", "", { "dependencies": { "@ctrl/tinycolor": "^3.4.1", "@element-plus/icons-vue": "^2.3.2", "@floating-ui/dom": "^1.0.1", "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", "@types/lodash": "^4.17.20", "@types/lodash-es": "^4.17.12", "@vueuse/core": "^10.11.0", "async-validator": "^4.2.5", "dayjs": "^1.11.19", "lodash": "^4.17.23", "lodash-es": "^4.17.23", "lodash-unified": "^1.0.3", "memoize-one": "^6.0.0", "normalize-wheel-es": "^1.2.0" }, "peerDependencies": { "vue": "^3.3.0" } }, "sha512-Zjzm1NnFXGhV4LYZ6Ze9skPlYi2B4KAmN18FL63A3PZcjhDfroHwhtM6RE8BonlOPHXUnPQynH0BgaoEfvhrGw=="],
@@ -1088,7 +1092,7 @@
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="], "ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "tslib": ["tslib@2.3.0", "", {}, "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="],
"tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="], "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
@@ -1154,6 +1158,8 @@
"vue-demi": ["vue-demi@0.14.10", "", { "peerDependencies": { "@vue/composition-api": "^1.0.0-rc.1", "vue": "^3.0.0-0 || ^2.6.0" }, "optionalPeers": ["@vue/composition-api"], "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", "vue-demi-switch": "bin/vue-demi-switch.js" } }, "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg=="], "vue-demi": ["vue-demi@0.14.10", "", { "peerDependencies": { "@vue/composition-api": "^1.0.0-rc.1", "vue": "^3.0.0-0 || ^2.6.0" }, "optionalPeers": ["@vue/composition-api"], "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", "vue-demi-switch": "bin/vue-demi-switch.js" } }, "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg=="],
"vue-echarts": ["vue-echarts@8.0.1", "", { "peerDependencies": { "echarts": "^6.0.0", "vue": "^3.3.0" } }, "sha512-23rJTFLu1OUEGRWjJGmdGt8fP+8+ja1gVgzMYPIPaHWpXegcO1viIAaeu2H4QHESlVeHzUAHIxKXGrwjsyXAaA=="],
"vue-eslint-parser": ["vue-eslint-parser@10.2.0", "", { "dependencies": { "debug": "^4.4.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.6.0", "semver": "^7.6.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" } }, "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw=="], "vue-eslint-parser": ["vue-eslint-parser@10.2.0", "", { "dependencies": { "debug": "^4.4.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.6.0", "semver": "^7.6.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" } }, "sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw=="],
"vue-i18n": ["vue-i18n@11.2.8", "", { "dependencies": { "@intlify/core-base": "11.2.8", "@intlify/shared": "11.2.8", "@vue/devtools-api": "^6.5.0" }, "peerDependencies": { "vue": "^3.0.0" } }, "sha512-vJ123v/PXCZntd6Qj5Jumy7UBmIuE92VrtdX+AXr+1WzdBHojiBxnAxdfctUFL+/JIN+VQH4BhsfTtiGsvVObg=="], "vue-i18n": ["vue-i18n@11.2.8", "", { "dependencies": { "@intlify/core-base": "11.2.8", "@intlify/shared": "11.2.8", "@vue/devtools-api": "^6.5.0" }, "peerDependencies": { "vue": "^3.0.0" } }, "sha512-vJ123v/PXCZntd6Qj5Jumy7UBmIuE92VrtdX+AXr+1WzdBHojiBxnAxdfctUFL+/JIN+VQH4BhsfTtiGsvVObg=="],
@@ -1182,10 +1188,14 @@
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
"zrender": ["zrender@6.0.0", "", { "dependencies": { "tslib": "2.3.0" } }, "sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg=="],
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
"@swc/helpers/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.5.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.5.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="],
@@ -1212,12 +1222,16 @@
"@vue/language-core/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "@vue/language-core/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"aria-hidden/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"element-plus/@vueuse/core": ["@vueuse/core@10.11.1", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "10.11.1", "@vueuse/shared": "10.11.1", "vue-demi": ">=0.14.8" } }, "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww=="], "element-plus/@vueuse/core": ["@vueuse/core@10.11.1", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "10.11.1", "@vueuse/shared": "10.11.1", "vue-demi": ">=0.14.8" } }, "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww=="],
"eslint-plugin-vue/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], "eslint-plugin-vue/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"framer-motion/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], "lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],

4
components.d.ts vendored
View File

@@ -28,6 +28,8 @@ declare module 'vue' {
ChangeLanguageDropdownButton: typeof import('./src/components/button/ChangeLanguageDropdownButton.vue')['default'] ChangeLanguageDropdownButton: typeof import('./src/components/button/ChangeLanguageDropdownButton.vue')['default']
ChangeThemeDropdownButton: typeof import('./src/components/button/ChangeThemeDropdownButton.vue')['default'] ChangeThemeDropdownButton: typeof import('./src/components/button/ChangeThemeDropdownButton.vue')['default']
DatePicker: typeof import('./src/components/date-picker/DatePicker.vue')['default'] DatePicker: typeof import('./src/components/date-picker/DatePicker.vue')['default']
DevelopProgressCard: typeof import('./src/components/card/DevelopProgressCard.vue')['default']
DevelopProgressDiagram: typeof import('./src/components/diagram/DevelopProgressDiagram.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton'] ElButton: typeof import('element-plus/es')['ElButton']
NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default'] NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default'] NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']
@@ -60,6 +62,8 @@ declare global {
const ChangeLanguageDropdownButton: typeof import('./src/components/button/ChangeLanguageDropdownButton.vue')['default'] const ChangeLanguageDropdownButton: typeof import('./src/components/button/ChangeLanguageDropdownButton.vue')['default']
const ChangeThemeDropdownButton: typeof import('./src/components/button/ChangeThemeDropdownButton.vue')['default'] const ChangeThemeDropdownButton: typeof import('./src/components/button/ChangeThemeDropdownButton.vue')['default']
const DatePicker: typeof import('./src/components/date-picker/DatePicker.vue')['default'] const DatePicker: typeof import('./src/components/date-picker/DatePicker.vue')['default']
const DevelopProgressCard: typeof import('./src/components/card/DevelopProgressCard.vue')['default']
const DevelopProgressDiagram: typeof import('./src/components/diagram/DevelopProgressDiagram.vue')['default']
const ElButton: typeof import('element-plus/es')['ElButton'] const ElButton: typeof import('element-plus/es')['ElButton']
const NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default'] const NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default']
const NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default'] const NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default']

View File

@@ -26,6 +26,7 @@ export default defineConfig({
{ text: "自动路由", link: "/cli-feature/auto-router" }, { text: "自动路由", link: "/cli-feature/auto-router" },
{ text: "组件库", link: "/cli-feature/component-lib" }, { text: "组件库", link: "/cli-feature/component-lib" },
{ text: "国际化", link: "/cli-feature/international" }, { text: "国际化", link: "/cli-feature/international" },
{ text: "图表", link: "/cli-feature/chart" },
], ],
}, },
], ],

42
docs/cli-feature/chart.md Normal file
View File

@@ -0,0 +1,42 @@
# 图表
## 使用
Hucky 选用 Echarts + Vue Echarts 组件库来为项目绘制图表。首先您需要熟悉如何使用 Echarts 的 option 来绘制一个图表,您可以前往 [Echarts 官方示例站点](https://echarts.apache.org/examples/zh/index.html) 先选择一个参考图表,然后复制其 option 代码。
然后您需要前往 [Vue Echarts 站点](https://vue-echarts.dev/#codegen) 并使用其提供的引入代码生成器来生成 import 代码。将您的 option 对象粘贴并获取对应的 import 代码。注意这里粘贴的是具体的 option 对象,而不是以 option = 开头的赋值语句。
接下来在您需要用到图表的组件中引入 vue echarts 提供的 VChart 组件。并动态绑定 option 到 VChart 组件的 props 中。可参考如下代码。
```vue
<script setup lang="ts">
import VChart from "vue-echarts";
import { type EChartsOption } from "echarts";
// 自动生成的 import 代码
import { use } from "echarts/core";
import { PieChart } from "echarts/charts";
import { TooltipComponent, LegendComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
use([TooltipComponent, LegendComponent, PieChart, CanvasRenderer]);
const option = ref<EChartsOption>({
// 此处为您复制的 Echarts 官方示例站点的 option 代码
});
</script>
<template>
<!-- 必须设置图表容器的高度和宽度 -->
<div class="h-96 w-96">
<VChart :option="option" />
</div>
</template>
<style scoped></style>
```
:::tip 提示
您可以前往 [Vue Echarts 文档](https://github.com/ecomfe/vue-echarts/blob/HEAD/README.zh-Hans.md) 查看更多使用方法。
:::

View File

@@ -21,6 +21,7 @@
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"daisyui": "^5.0.50", "daisyui": "^5.0.50",
"echarts": "^6.0.0",
"element-plus": "^2.13.2", "element-plus": "^2.13.2",
"lucide-vue-next": "^0.563.0", "lucide-vue-next": "^0.563.0",
"motion-v": "^1.6.1", "motion-v": "^1.6.1",
@@ -30,6 +31,7 @@
"reka-ui": "^2.8.0", "reka-ui": "^2.8.0",
"tailwind-merge": "^3.4.0", "tailwind-merge": "^3.4.0",
"vue": "^3.5.17", "vue": "^3.5.17",
"vue-echarts": "^8.0.1",
"vue-i18n": "11", "vue-i18n": "11",
"vue-router": "^4.5.1" "vue-router": "^4.5.1"
}, },

View File

@@ -0,0 +1,27 @@
<script setup lang="ts">
import DevelopProgressDiagram from "../diagram/DevelopProgressDiagram.vue";
const props = defineProps<{
completed: number;
pending: number;
title: string;
intro: string;
}>();
</script>
<template>
<div class="card bg-base-100 w-96 shadow-sm">
<DevelopProgressDiagram
:completed="props.completed"
:pending="props.pending"
/>
<div class="card-body">
<h2 class="card-title">{{ props.title }}</h2>
<p>
{{ props.intro }}
</p>
</div>
</div>
</template>
<style scoped></style>

View File

@@ -0,0 +1,62 @@
<script setup lang="ts">
import { use } from "echarts/core";
import { PieChart } from "echarts/charts";
import { TooltipComponent, LegendComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
import VChart from "vue-echarts";
import { type EChartsOption } from "echarts";
use([TooltipComponent, LegendComponent, PieChart, CanvasRenderer]);
const props = defineProps<{
completed: number;
pending: number;
}>();
const option = ref<EChartsOption>({
color: ["#52c41a", "#ff4d4f"],
legend: {
top: "5%",
left: "center",
},
series: [
{
name: "开发进度",
type: "pie",
radius: ["40%", "70%"],
itemStyle: {
borderRadius: 10,
borderColor: "#fff",
borderWidth: 2,
},
label: {
show: false,
position: "center",
},
labelLine: {
show: false,
},
emphasis: {
label: {
show: true,
fontSize: 32,
fontWeight: "bold",
formatter: "{d}%",
},
},
data: [
{ value: props.completed, name: "已完成" },
{ value: props.pending, name: "待开发" },
],
},
],
});
</script>
<template>
<div class="h-96 w-96">
<VChart :option="option" />
</div>
</template>
<style scoped></style>

View File

@@ -1,14 +1,51 @@
<script lang="ts" setup> <script lang="ts" setup>
import DatePicker from "@/components/date-picker/DatePicker.vue"; import DevelopProgressCard from "@/components/card/DevelopProgressCard.vue";
import NavBar from "@/components/menu/NavBar.vue"; import NavBar from "@/components/menu/NavBar.vue";
const progress = ref([
{
name: "auto-router",
completed: 80,
pending: 20,
title: "自动路由开发进度",
intro: "自动将 pages 目录下的所有 vue 文件转换为路由",
},
{
name: "component-list",
completed: 95,
pending: 5,
title: "组件库开发进度",
intro: "自动加载项目所需要的组件库",
},
{
name: "international",
completed: 95,
pending: 5,
title: "国际化开发进度",
intro: "有序地组织项目翻译文件",
},
{
name: "chart",
completed: 95,
pending: 5,
title: "图表开发进度",
intro: "使用精美的图表呈现内容",
},
]);
</script> </script>
<template> <template>
<div> <div>
<NavBar /> <NavBar />
<div class="mt-4"> <div class="w-full p-4 grid grid-cols-3 gap-4 justify-items-center">
<div>路由系统加载进度100%</div> <DevelopProgressCard
<DatePicker /> v-for="item in progress"
:key="item.title"
:completed="item.completed"
:pending="item.pending"
:title="item.title"
:intro="item.intro"
/>
</div> </div>
</div> </div>
</template> </template>