├── .editorconfig ├── .env ├── .env.development ├── .env.production ├── .env.sit ├── .env.uat ├── .eslintignore ├── .eslintrc.js ├── .gitattributes ├── .gitignore ├── .husky ├── commit-msg ├── common.sh └── pre-commit ├── .prettierignore ├── .prettierrc ├── .vscode └── extensions.json ├── LICENSE ├── README.md ├── README.zh-CN.md ├── build ├── index.ts ├── loader │ └── svgComponent.ts ├── plugin │ ├── autoImport.ts │ ├── cdnImport.ts │ ├── components.ts │ ├── compression.ts │ ├── html.ts │ ├── imageOptimize.ts │ └── visualizer.ts ├── proxy.ts └── utils.ts ├── commitlint.config.cjs ├── env.d.ts ├── index.html ├── package.json ├── preview.png ├── public └── favicon.ico ├── src ├── App.vue ├── assets │ ├── base.css │ ├── logo.svg │ └── main.css ├── components │ ├── HelloWorld.vue │ ├── TheWelcome.vue │ ├── WelcomeItem.vue │ └── icons │ │ ├── IconCommunity.vue │ │ ├── IconDocumentation.vue │ │ ├── IconEcosystem.vue │ │ ├── IconSupport.vue │ │ └── IconTooling.vue ├── main.ts ├── router │ └── index.ts ├── stores │ └── counter.ts └── views │ ├── AboutView.vue │ ├── HomeView.vue │ └── Layout.vue ├── tsconfig.json ├── types ├── auto-imports.d.ts ├── components.d.ts └── global.d.ts └── vite.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset=utf-8 3 | end_of_line=lf 4 | insert_final_newline=false 5 | indent_style=space 6 | indent_size=2 7 | 8 | [{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}] 9 | indent_style=space 10 | indent_size=2 11 | 12 | [{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}] 13 | indent_style=space 14 | indent_size=2 15 | 16 | [{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}] 17 | indent_style=space 18 | indent_size=2 19 | 20 | [*.svg] 21 | indent_style=space 22 | indent_size=2 23 | 24 | [*.js.map] 25 | indent_style=space 26 | indent_size=2 27 | 28 | [{*.less,*.scss,*.stylus}] 29 | indent_style=space 30 | indent_size=2 31 | 32 | [*.vue] 33 | indent_style=space 34 | indent_size=2 35 | 36 | [{.analysis_options,*.yml,*.yaml}] 37 | indent_style=space 38 | indent_size=2 39 | 40 | [*.md] 41 | trim_trailing_whitespace = false 42 | 43 | [Makefile] 44 | indent_style = tab 45 | 46 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # title 2 | VITE_GLOB_APP_TITLE=antd-vue3-admin 3 | -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | # .env.development 2 | VITE_APP_NODE_ENV=development 3 | 4 | # 端口号 5 | VITE_PORT=5173 6 | 7 | # 是否开启mock,关闭时需要自行对接后台接口 8 | # VITE_USE_MOCK=true 9 | 10 | # 本地开发代理,可以解决跨域及多地址代理 11 | VITE_PROXY=[["/api","http://localhost:3000"],["api1","http://localhost:3001"],["/upload","http://localhost:3001/upload"]] 12 | # VITE_PROXY=[["/api","https://your-legacy/test"]] 13 | 14 | # 本地接口地址代理路径 15 | VITE_GLOB_API_URL=/api 16 | 17 | # 接口地址前缀 18 | VITE_GLOB_API_URL_PREFIX= -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | # .env.production 2 | VITE_APP_NODE_ENV=production 3 | 4 | # 是否开启mock 5 | # VITE_USE_MOCK=false 6 | 7 | # 是否启用pwa 8 | # VITE_USE_PWA=false 9 | 10 | # 是否使用cdn 11 | VITE_USE_CDN=true 12 | 13 | # 是否压缩图片 14 | VITE_USE_IMAGEMIN=true 15 | 16 | # 是否移除日志及debugger 17 | VITE_DROP_CONSOLE=true 18 | 19 | # 服务端接口地址 20 | VITE_GLOB_API_URL_PREFIX=http://your-interface-path/api 21 | 22 | # 是否输出gz|br文件 23 | # 可选: gzip | brotli | none 24 | # 也可以有多个, 例如 gzip|brotli,这样会同时生成 .gz和.br文件 25 | VITE_BUILD_COMPRESS=gzip 26 | 27 | # 是否删除源文件 28 | VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE=false 29 | -------------------------------------------------------------------------------- /.env.sit: -------------------------------------------------------------------------------- 1 | # .env.production 2 | VITE_APP_NODE_ENV=production 3 | 4 | # 是否开启mock 5 | # VITE_USE_MOCK=false 6 | 7 | # 是否启用pwa 8 | # VITE_USE_PWA=false 9 | 10 | # 是否使用cdn 11 | VITE_USE_CDN=true 12 | 13 | # 是否压缩图片 14 | VITE_USE_IMAGEMIN=true 15 | 16 | # 是否移除日志及debugger 17 | VITE_DROP_CONSOLE=true 18 | 19 | # 服务端接口地址 20 | VITE_GLOB_API_URL=http://your-interface-path-sit/api 21 | 22 | # 服务端接口地址前缀 23 | VITE_GLOB_API_URL_PREFIX= 24 | 25 | # 是否输出gz|br文件 26 | # 可选: gzip | brotli | none 27 | # 也可以有多个, 例如 gzip|brotli,这样会同时生成 .gz和.br文件 28 | VITE_BUILD_COMPRESS=gzip 29 | 30 | # 是否删除源文件 31 | VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE=false 32 | -------------------------------------------------------------------------------- /.env.uat: -------------------------------------------------------------------------------- 1 | # .env.production 2 | VITE_APP_NODE_ENV=production 3 | 4 | # 是否开启mock 5 | # VITE_USE_MOCK=false 6 | 7 | # 是否启用pwa 8 | # VITE_USE_PWA=false 9 | 10 | # 是否使用cdn 11 | VITE_USE_CDN=true 12 | 13 | # 是否压缩图片 14 | VITE_USE_IMAGEMIN=true 15 | 16 | # 是否移除日志及debugger 17 | VITE_DROP_CONSOLE=true 18 | 19 | # 服务端接口地址 20 | VITE_GLOB_API_URL=https://your-interface-path-uat.h3c.com 21 | 22 | # 服务端接口地址前缀 23 | VITE_GLOB_API_URL_PREFIX= 24 | 25 | # 是否输出gz|br文件 26 | # 可选: gzip | brotli | none 27 | # 也可以有多个, 例如 gzip|brotli,这样会同时生成 .gz和.br文件 28 | VITE_BUILD_COMPRESS=gzip 29 | 30 | # 是否删除源文件 31 | VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE=false 32 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | 2 | *.json 3 | *.html 4 | *rc.js 5 | *.svg 6 | *.woff 7 | *.ttf 8 | *.css 9 | *.sh 10 | *.md 11 | 12 | .vscode 13 | .idea 14 | 15 | package.json 16 | 17 | # Dependency directories 18 | node_modules/ 19 | 20 | # local env files 21 | .env.local 22 | .env.*.local 23 | 24 | .husky 25 | /bin 26 | /deploy 27 | /dist 28 | /docs 29 | /public 30 | /src/assets 31 | /src/mock 32 | 33 | # deps exclude 34 | types/auto-imports.d.ts 35 | types/components.d.ts 36 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require('@rushstack/eslint-patch/modern-module-resolution'); 3 | 4 | module.exports = { 5 | root: true, 6 | env: { 7 | browser: true, 8 | node: true, 9 | es6: true, 10 | }, 11 | parser: 'vue-eslint-parser', 12 | parserOptions: { 13 | parser: '@typescript-eslint/parser', 14 | ecmaVersion: 2020, 15 | sourceType: 'module', 16 | jsxPragma: 'React', 17 | ecmaFeatures: { 18 | jsx: true, 19 | tsx: true, 20 | }, 21 | }, 22 | extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], 23 | rules: { 24 | // js 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 26 | // prettier 27 | 'prettier/prettier': [ 28 | 2, 29 | { 30 | usePrettierrc: true, 31 | }, 32 | ], 33 | // vue 34 | 'vue/max-attributes-per-line': [ 35 | 2, 36 | { 37 | singleline: 5, 38 | multiline: 1, 39 | }, 40 | ], 41 | 'vue/attribute-hyphenation': 0, 42 | 'vue/component-name-in-template-casing': 0, 43 | 'vue/html-closing-bracket-spacing': 0, 44 | 'vue/singleline-html-element-content-newline': 0, 45 | 'vue/script-setup-uses-vars': 2, 46 | 'vue/no-unused-components': 0, 47 | 'vue/multiline-html-element-content-newline': 0, 48 | 'vue/no-use-v-if-with-v-for': 0, 49 | 'vue/html-closing-bracket-newline': 0, 50 | 'vue/no-parsing-error': 0, 51 | 'vue/multi-word-component-names': 0, 52 | 'vue/no-mutating-props': 0, 53 | 'vue/custom-event-name-casing': 0, 54 | 'vue/attributes-order': 0, 55 | 'vue/one-component-per-file': 0, 56 | 'vue/require-default-prop': 0, 57 | 'vue/require-explicit-emits': 0, 58 | 'vue/html-self-closing': [ 59 | 2, 60 | { 61 | html: { 62 | void: 'always', 63 | // normal: 'never', 64 | component: 'always', 65 | }, 66 | svg: 'always', 67 | math: 'always', 68 | }, 69 | ], 70 | // ts 71 | '@typescript-eslint/ban-ts-ignore': 0, 72 | '@typescript-eslint/explicit-function-return-type': 0, 73 | '@typescript-eslint/no-explicit-any': 0, 74 | '@typescript-eslint/no-var-requires': 0, 75 | '@typescript-eslint/no-empty-function': 0, 76 | '@typescript-eslint/no-use-before-define': 0, 77 | '@typescript-eslint/ban-ts-comment': 0, 78 | '@typescript-eslint/ban-types': 0, 79 | '@typescript-eslint/no-non-null-assertion': 0, 80 | '@typescript-eslint/explicit-module-boundary-types': 0, 81 | '@typescript-eslint/no-unused-vars': [ 82 | 'error', 83 | { 84 | argsIgnorePattern: '^_', 85 | varsIgnorePattern: '^_', 86 | }, 87 | ], 88 | }, 89 | }; 90 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/cn/get-started/getting-started-with-git/configuring-git-to-handle-line-endings 2 | 3 | # Automatically normalize line endings (to LF) for all text-based files. 4 | * text=auto eol=lf 5 | 6 | # Declare files that will always have CRLF line endings on checkout. 7 | *.{cmd,[cC][mM][dD]} text eol=crlf 8 | *.{bat,[bB][aA][tT]} text eol=crlf 9 | 10 | # Denote all files that are truly binary and should not be modified. 11 | *.{ico,png,jpg,jpeg,gif,webp,svg,woff,woff2} binary -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | # dependencies version lock file 31 | package-lock.json 32 | pnpm-lock.yaml 33 | yarn.lock 34 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | . "$(dirname "$0")/common.sh" 4 | 5 | npx commitlint --edit $1 6 | -------------------------------------------------------------------------------- /.husky/common.sh: -------------------------------------------------------------------------------- 1 | command_exists () { 2 | command -v "$1" >/dev/null 2>&1 3 | } 4 | 5 | # Workaround for Windows 10, Git Bash and Yarn 6 | if command_exists winpty && test -t 1; then 7 | exec < /dev/tty 8 | fi 9 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | . "$(dirname "$0")/common.sh" 4 | 5 | npx lint-staged 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Project Files 4 | .husky/ 5 | deploy/ 6 | node_modules/ 7 | dist/ 8 | docs/ 9 | plugins/ 10 | public/ 11 | CNAME 12 | LICENSE 13 | **/assets 14 | 15 | # Dependencies version lock file 16 | package-lock.json 17 | pnpm-lock.yaml 18 | yarn.lock 19 | 20 | # Logs 21 | logs 22 | *.log 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | pnpm-debug.log* 27 | lerna-debug.log* 28 | 29 | # Editor directories and files 30 | .vscode/* 31 | !.vscode/extensions.json 32 | .idea 33 | *.suo 34 | *.ntvs* 35 | *.njsproj 36 | *.sln 37 | *.sw? 38 | *.sh 39 | *.snap 40 | *.png 41 | *.yml 42 | 43 | # Other 44 | .eslintignore 45 | .gitmodules 46 | .gitattributes 47 | .gitignore 48 | .prettierignore 49 | .npmignore 50 | .editorconfig 51 | .stylelintrc 52 | .vcmrc 53 | .npmrc.template 54 | .huskyrc 55 | 56 | netlify.toml 57 | Dockerfile 58 | Jenkinsfile 59 | 60 | # deps exclude 61 | types/auto-imports.d.ts 62 | types/components.d.ts 63 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "semi": true, 4 | "vueIndentScriptAndStyle": true, 5 | "singleQuote": true, 6 | "trailingComma": "all", 7 | "proseWrap": "never", 8 | "arrowParens": "avoid", 9 | "htmlWhitespaceSensitivity": "strict", 10 | "endOfLine": "auto" 11 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.Vue-Official", "EditorConfig.EditorConfig"] 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-PRESENT ZuoJt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

antd-vue3-admin

2 | 3 | **English** | [中文](README.zh-CN.md) 4 | 5 | ## Introduction 6 | 7 | A mid-backend development template project based on vue3, vite4 and ant-design-vue4. Using the latest vue3, vite4, TypeScript5 and other cutting-edge technologies, out-of-the-box front-end solutions can be used for learning and business development. 8 | 9 | ![./preview.png](./preview.png) 10 | 11 | ## Recommended IDE Setup 12 | 13 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). 14 | 15 | ## Type Support for `.vue` Imports in TS 16 | 17 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. 18 | 19 | If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: 20 | 21 | 1. Disable the built-in TypeScript Extension 22 | 1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette 23 | 2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` 24 | 2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. 25 | 26 | ## Customize configuration 27 | 28 | See [Vite Configuration Reference](https://vitejs.dev/config/). 29 | 30 | ## Project Setup 31 | 32 | ```sh 33 | pnpm install 34 | ``` 35 | 36 | ### Compile and Hot-Reload for Development 37 | 38 | ```sh 39 | pnpm run dev 40 | ``` 41 | 42 | ### Type-Check, Compile and Minify for Production 43 | 44 | ```sh 45 | pnpm run build 46 | ``` 47 | 48 | ### Lint with [ESLint](https://eslint.org/) 49 | 50 | ```sh 51 | pnpm run lint 52 | ``` 53 | -------------------------------------------------------------------------------- /README.zh-CN.md: -------------------------------------------------------------------------------- 1 |

antd-vue3-admin

2 | 3 | **中文** | [English](README.md) 4 | 5 | ## 简介 6 | 7 | 一个基于 vue3,vite4 和 ant-design-vue4 的中后台开发模板工程。使用最新的`vue3`, `vite4`, `TypeScript5`等前沿技术,开箱即用的前端解决方案,可用于学习及业务开发。 8 | 9 | ![./preview.png](./preview.png) 10 | 11 | ## Recommended IDE Setup 12 | 13 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (禁用 Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). 14 | 15 | ## Type Support for `.vue` Imports in TS 16 | 17 | 默认情况下,TypeScript 无法处理 .vue 导入的类型信息,因此我们将 tsc CLI 替换为 vue-tsc 以进行类型检查。在编辑器中,我们需要 [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) 来让 TypeScript 语言服务识别 .vue 类型。 18 | 19 | 如果您觉得独立的 TypeScript 插件不够快,Volar 还实现了性能更高的[接管模式](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669)。您可以通过以下步骤启用它: 20 | 21 | 1. 禁用内置的 TypeScript 扩展 22 | 1. 从 VSCode 的命令面板运行 `Extensions: Show Built-in Extensions` 23 | 2. 找到 `TypeScript and JavaScript Language Features` ,右键单击并选择 `Disable (Workspace)` 24 | 2. 通过从命令面板运行“Developer: Reload Window”重新加载 VSCode 窗口. 25 | 26 | ## Customize configuration 27 | 28 | 查看 [配置 Vite](https://cn.vitejs.dev/config/). 29 | 30 | ## Project Setup 31 | 32 | ```sh 33 | pnpm install 34 | ``` 35 | 36 | ### Compile and Hot-Reload for Development 37 | 38 | ```sh 39 | pnpm run dev 40 | ``` 41 | 42 | ### Type-Check, Compile and Minify for Production 43 | 44 | ```sh 45 | pnpm run build 46 | ``` 47 | 48 | ### Lint with [ESLint](https://eslint.org/) 49 | 50 | ```sh 51 | pnpm run lint 52 | ``` 53 | -------------------------------------------------------------------------------- /build/index.ts: -------------------------------------------------------------------------------- 1 | import type { PluginOption } from 'vite'; 2 | import { isProd, isReport } from './utils'; 3 | 4 | import { configLoaderSvg } from './loader/svgComponent'; 5 | 6 | import { configPluginHTML } from './plugin/html'; 7 | import { configPluginAutoImport } from './plugin/autoImport'; 8 | import { configPluginComponents } from './plugin/components'; 9 | import { configPluginCDNImport } from './plugin/cdnImport'; 10 | import { configPluginCompression } from './plugin/compression'; 11 | import { configPluginImageOptimizer } from './plugin/imageOptimize'; 12 | import { configPluginVisualizer } from './plugin/visualizer'; 13 | 14 | export function vitePluginConfig(viteEnv: ViteEnv) { 15 | const { 16 | VITE_USE_CDN, 17 | VITE_GLOB_APP_TITLE, 18 | VITE_APP_NODE_ENV, 19 | VITE_BUILD_COMPRESS, 20 | VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE, 21 | VITE_USE_IMAGEMIN, 22 | } = viteEnv; 23 | 24 | const isProdMode = isProd(VITE_APP_NODE_ENV ?? ''); 25 | const isReportMode = isReport(); 26 | 27 | const vitePlugins: (PluginOption | PluginOption[])[] = []; 28 | 29 | // vite-svg-loader 30 | vitePlugins.push(configLoaderSvg()); 31 | 32 | // vite-plugin-html 33 | vitePlugins.push(configPluginHTML(VITE_GLOB_APP_TITLE ?? '')); 34 | 35 | // unplugin-auto-import 36 | vitePlugins.push(configPluginAutoImport()); 37 | 38 | // unplugin-vue-components 39 | vitePlugins.push(configPluginComponents()); 40 | 41 | // vite-plugin-cdn-import 42 | isProdMode && VITE_USE_CDN && vitePlugins.push(configPluginCDNImport()); 43 | 44 | // vite-plugin-compression 45 | isProdMode && 46 | vitePlugins.push(configPluginCompression(VITE_BUILD_COMPRESS ?? 'gzip', VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE)); 47 | 48 | // vite-plugin-image-optimizer 49 | isProdMode && VITE_USE_IMAGEMIN && vitePlugins.push(configPluginImageOptimizer()); 50 | 51 | // rollup-plugin-visualizer 52 | isReportMode && vitePlugins.push(configPluginVisualizer()); 53 | 54 | return vitePlugins; 55 | } 56 | -------------------------------------------------------------------------------- /build/loader/svgComponent.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/jpkleemans/vite-svg-loader 2 | import type { PluginOption } from 'vite'; 3 | import svgLoader from 'vite-svg-loader'; 4 | 5 | export function configLoaderSvg(): PluginOption | PluginOption[] { 6 | return svgLoader({ 7 | defaultImport: 'url', // or 'raw' 8 | }); 9 | } 10 | -------------------------------------------------------------------------------- /build/plugin/autoImport.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/antfu/unplugin-auto-import 2 | import type { PluginOption } from 'vite'; 3 | import AutoImport from 'unplugin-auto-import/vite'; 4 | 5 | export function configPluginAutoImport(): PluginOption | PluginOption[] { 6 | return AutoImport({ 7 | imports: [ 8 | 'vue', 9 | 'vue-router', 10 | { 11 | '@vueuse/core': [ 12 | // named imports 13 | 'useMouse', // import { useMouse } from '@vueuse/core', 14 | 'usePreferredDark', 15 | 'useDark', 16 | 'useTitle', 17 | // alias 18 | ['useFetch', 'useMyFetch'], // import { useFetch as useMyFetch } from '@vueuse/core', 19 | ], 20 | axios: [ 21 | // default imports 22 | ['default', 'axios'], // import { default as axios } from 'axios', 23 | ], 24 | }, 25 | ], 26 | // resolvers: [AntDesignVueResolver()], 27 | vueTemplate: true, 28 | dirs: ['src/hooks', 'src/components'], 29 | dts: 'types/auto-imports.d.ts', 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /build/plugin/cdnImport.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/Zuojiangtao/vite-plugin-external-cdn 2 | import type { PluginOption } from 'vite'; 3 | import transformExternalCDN, { autoComplete } from 'vite-plugin-external-cdn'; 4 | 5 | export function configPluginCDNImport(): PluginOption | PluginOption[] { 6 | return transformExternalCDN({ 7 | modules: [ 8 | autoComplete('vue'), // vue2 使用 autoComplete('vue2') 9 | autoComplete('axios'), 10 | autoComplete('@vueuse/shared'), 11 | autoComplete('@vueuse/core'), 12 | { 13 | name: 'vue-router', 14 | var: 'VueRouter', 15 | version: '4.5.0', 16 | path: 'dist/vue-router.global.min.js', 17 | }, 18 | { 19 | name: 'vue-demi', 20 | var: 'VueDemi', 21 | version: '0.14.7', 22 | path: 'lib/index.iife.min.js', 23 | }, 24 | { 25 | name: 'pinia', 26 | var: 'Pinia', 27 | version: '2.1.7', 28 | path: 'dist/pinia.iife.min.js', 29 | }, 30 | ], 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /build/plugin/components.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/antfu/unplugin-vue-components 2 | import type { PluginOption } from 'vite'; 3 | import Components from 'unplugin-vue-components/vite'; 4 | import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'; 5 | 6 | export function configPluginComponents(): PluginOption | PluginOption[] { 7 | return Components({ 8 | resolvers: [ 9 | AntDesignVueResolver({ 10 | importStyle: 'less', 11 | resolveIcons: true, 12 | }), 13 | ], 14 | dts: 'types/components.d.ts', 15 | include: [/\.vue$/, /\.vue\?vue/, /\.md$/], 16 | version: 3, 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /build/plugin/compression.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/anncwb/vite-plugin-compression 2 | import type { PluginOption } from 'vite'; 3 | import vitePluginCompression from 'vite-plugin-compression'; 4 | 5 | export function configPluginCompression( 6 | compress: 'gzip' | 'brotli' | 'none', 7 | deleteOriginFile = false, 8 | ): PluginOption | PluginOption[] { 9 | const compressList: string[] = compress.split('|'); 10 | 11 | const plugins: PluginOption[] = []; 12 | 13 | if (compressList.includes('gzip')) { 14 | plugins.push( 15 | vitePluginCompression({ 16 | ext: '.gz', 17 | deleteOriginFile, 18 | }), 19 | ); 20 | } 21 | 22 | if (compressList.includes('brotli')) { 23 | plugins.push( 24 | vitePluginCompression({ 25 | ext: '.br', 26 | algorithm: 'brotliCompress', 27 | deleteOriginFile, 28 | }), 29 | ); 30 | } 31 | 32 | return plugins; 33 | } 34 | -------------------------------------------------------------------------------- /build/plugin/html.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/anncwb/vite-plugin-html 2 | import type { PluginOption } from 'vite'; 3 | import { createHtmlPlugin } from 'vite-plugin-html'; 4 | 5 | export function configPluginHTML(title: string): PluginOption | PluginOption[] { 6 | return createHtmlPlugin({ 7 | minify: true, 8 | entry: 'src/main.ts', 9 | inject: { 10 | // Inject data into ejs template 11 | data: { 12 | title, 13 | }, 14 | // tags: [ 15 | // { 16 | // tag: 'script', 17 | // attrs: { 18 | // src: '/assets/', 19 | // }, 20 | // }, 21 | // ], 22 | }, 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /build/plugin/imageOptimize.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/FatehAK/vite-plugin-image-optimizer 2 | import type { PluginOption } from 'vite'; 3 | import { ViteImageOptimizer } from 'vite-plugin-image-optimizer'; 4 | 5 | export function configPluginImageOptimizer(): PluginOption | PluginOption[] { 6 | return ViteImageOptimizer({ 7 | cache: true, 8 | cacheLocation: './node_modules/.cache/imageOptimizer', 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /build/plugin/visualizer.ts: -------------------------------------------------------------------------------- 1 | // https://github.com/btd/rollup-plugin-visualizer 2 | import type { PluginOption } from 'vite'; 3 | import visualizer from 'rollup-plugin-visualizer'; 4 | 5 | export function configPluginVisualizer(): PluginOption | PluginOption[] { 6 | return visualizer({ 7 | // template: 'treemap', // sunburst | treemap | network | raw-data | list 8 | filename: './node_modules/.cache/visualizer/stats.html', 9 | open: true, 10 | gzipSize: true, 11 | brotliSize: true, 12 | }) as PluginOption; 13 | } 14 | -------------------------------------------------------------------------------- /build/proxy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Used to parse the .env.development proxy configuration 3 | */ 4 | import type { ProxyOptions } from 'vite'; 5 | 6 | type ProxyItem = [string, string]; 7 | 8 | type ProxyList = ProxyItem[]; 9 | 10 | type ProxyTargetList = Record; 11 | 12 | const httpsRE = /^https:\/\//; 13 | 14 | /** 15 | * Generate proxy 16 | * @param list 17 | */ 18 | export function createProxy(list: ProxyList = []) { 19 | const ret: ProxyTargetList = {}; 20 | for (const [prefix, target] of list) { 21 | const isHttps = httpsRE.test(target); 22 | 23 | // https://github.com/http-party/node-http-proxy#options 24 | ret[prefix] = { 25 | target: target, 26 | changeOrigin: true, 27 | ws: true, 28 | rewrite: path => path.replace(new RegExp(`^${prefix}`), ''), 29 | // https is require secure=false 30 | ...(isHttps ? { secure: false } : {}), 31 | }; 32 | } 33 | return ret; 34 | } 35 | -------------------------------------------------------------------------------- /build/utils.ts: -------------------------------------------------------------------------------- 1 | // utils 2 | import * as process from 'process'; 3 | 4 | export function isDev(VITE_APP_NODE_ENV: string): boolean { 5 | return VITE_APP_NODE_ENV === 'development'; 6 | } 7 | 8 | export function isProd(VITE_APP_NODE_ENV: string): boolean { 9 | return VITE_APP_NODE_ENV === 'production'; 10 | } 11 | 12 | export function isReport(): boolean { 13 | return process.env.REPORT === 'true'; 14 | } 15 | 16 | // 转换env.production文件配置字段数据类型 17 | export function transformEnvConfType(envConf: Recordable): ViteEnv { 18 | const ret: any = {}; 19 | 20 | for (const envKey of Object.keys(envConf)) { 21 | let realName = envConf[envKey].replace(/\\n/g, '\n'); 22 | realName = realName === 'true' ? true : realName === 'false' ? false : realName; 23 | 24 | if (envKey === 'VITE_PORT') { 25 | realName = Number(realName); 26 | } 27 | if (envKey === 'VITE_PROXY' && realName) { 28 | try { 29 | realName = JSON.parse(realName.replace(/'/g, '"')); 30 | } catch (error) { 31 | realName = ''; 32 | } 33 | } 34 | ret[envKey] = realName; 35 | // if (typeof realName === 'string') { 36 | // process.env[envName] = realName; 37 | // } else if (typeof realName === 'object') { 38 | // process.env[envName] = JSON.stringify(realName); 39 | // } 40 | } 41 | return ret; 42 | } 43 | -------------------------------------------------------------------------------- /commitlint.config.cjs: -------------------------------------------------------------------------------- 1 | /** 2 | * feat:新增功能 3 | * fix:bug 修复 4 | * docs:文档更新 5 | * style:不影响程序逻辑的代码修改(修改空白字符,格式缩进,补全缺失的分号等,没有改变代码逻辑) 6 | * refactor:重构代码(既没有新增功能,也没有修复 bug) 7 | * perf:性能, 体验优化 8 | * test:新增测试用例或是更新现有测试 9 | * build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交 10 | * ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle等)的提交 11 | * chore:不属于以上类型的其他类型,比如构建流程, 依赖管理 12 | * revert:回滚某个更早之前的提交 13 | */ 14 | 15 | module.exports = { 16 | extends: ['@commitlint/config-conventional'], 17 | rules: { 18 | 'type-enum': [ 19 | 2, 20 | 'always', 21 | ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert'], 22 | ], 23 | 'subject-full-stop': [0, 'never'], 24 | 'subject-case': [0, 'never'], 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | interface ImportMetaNodeEnv { 4 | readonly VITE_APP_ENV: string; 5 | } 6 | 7 | interface ImportMetaBaseUrl { 8 | readonly VITE_APP_BASE_URL: string; 9 | } 10 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= title %> 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "antd-vue3-admin", 3 | "version": "1.0.0", 4 | "author": { 5 | "name": "Zuojiangtao", 6 | "email": "1799158837@qq.com", 7 | "url": "https://github.com/Zuojiangtao" 8 | }, 9 | "keywords": [ 10 | "vue", 11 | "vue3", 12 | "vite", 13 | "vite4", 14 | "ant-design-vue", 15 | "typescript", 16 | "ts", 17 | "admin", 18 | "template" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/Zuojiangtao/antd-vue3-admin.git" 23 | }, 24 | "homepage": "https://github.com/Zuojiangtao/antd-vue3-admin", 25 | "license": "MIT", 26 | "scripts": { 27 | "dev": "vite", 28 | "build:sit": "vite build --mode sit", 29 | "build:uat": "vite build --mode uat", 30 | "build": "run-p type-check build-only", 31 | "preview": "vite preview --port 4173", 32 | "build-only": "vite build", 33 | "report": "cross-env REPORT=true npm run build", 34 | "type-check": "vue-tsc --noEmit", 35 | "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite", 36 | "clean:lib": "rimraf node_modules", 37 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", 38 | "prepare": "husky install", 39 | "lint-staged": "lint-staged" 40 | }, 41 | "lint-staged": { 42 | "src/**/*.{ts,js,json,tsx,jsx,vue}": [ 43 | "prettier --write", 44 | "eslint --cache --fix", 45 | "eslint" 46 | ] 47 | }, 48 | "dependencies": { 49 | "@ant-design/icons-vue": "^7.0.1", 50 | "@vueuse/core": "^12.2.0", 51 | "@vueuse/shared": "^12.2.0", 52 | "ant-design-vue": "4.2.6", 53 | "axios": "^1.7.9", 54 | "pinia": "^2.1.7", 55 | "vue": "^3.5.13", 56 | "vue-demi": "^0.14.7", 57 | "vue-router": "4.5.0" 58 | }, 59 | "devDependencies": { 60 | "@commitlint/cli": "^19.2.1", 61 | "@commitlint/config-conventional": "^19.1.0", 62 | "@rushstack/eslint-patch": "^1.8.0", 63 | "@types/node": "^20.11.30", 64 | "@vitejs/plugin-vue": "^4.6.2", 65 | "@vitejs/plugin-vue-jsx": "^3.1.0", 66 | "@vue/eslint-config-prettier": "^9.0.0", 67 | "@vue/eslint-config-typescript": "^13.0.0", 68 | "@vue/tsconfig": "^0.5.1", 69 | "cross-env": "^7.0.3", 70 | "eslint": "^8.57.1", 71 | "eslint-plugin-vue": "^9.23.0", 72 | "husky": "^9.0.11", 73 | "less": "^4.2.0", 74 | "lint-staged": "^15.2.0", 75 | "npm-run-all": "^4.1.5", 76 | "prettier": "^3.2.5", 77 | "rimraf": "^6.0.1", 78 | "rollup-plugin-visualizer": "^5.12.0", 79 | "sharp": "^0.33.1", 80 | "svgo": "^3.2.0", 81 | "typescript": "^5.4.3", 82 | "unplugin-auto-import": "^0.19.0", 83 | "unplugin-vue-components": "^0.27.5", 84 | "vite": "^4.5.2", 85 | "vite-plugin-compression": "^0.5.1", 86 | "vite-plugin-external-cdn": "^1.0.1", 87 | "vite-plugin-html": "^3.2.2", 88 | "vite-plugin-image-optimizer": "^1.1.8", 89 | "vite-svg-loader": "^5.1.0", 90 | "vue-tsc": "^2.1.10" 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zuojiangtao/antd-vue3-admin/4e27ae2598c63b48ae587f98757f330e7197cc5c/preview.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Zuojiangtao/antd-vue3-admin/4e27ae2598c63b48ae587f98757f330e7197cc5c/public/favicon.ico -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 23 | 24 | 87 | -------------------------------------------------------------------------------- /src/assets/base.css: -------------------------------------------------------------------------------- 1 | /* color palette from */ 2 | :root { 3 | --vt-c-white: #ffffff; 4 | --vt-c-white-soft: #f8f8f8; 5 | --vt-c-white-mute: #f2f2f2; 6 | 7 | --vt-c-black: #181818; 8 | --vt-c-black-soft: #222222; 9 | --vt-c-black-mute: #282828; 10 | 11 | --vt-c-indigo: #2c3e50; 12 | 13 | --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); 14 | --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); 15 | --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); 16 | --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); 17 | 18 | --vt-c-text-light-1: var(--vt-c-indigo); 19 | --vt-c-text-light-2: rgba(60, 60, 60, 0.66); 20 | --vt-c-text-dark-1: var(--vt-c-white); 21 | --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); 22 | } 23 | 24 | /* semantic color variables for this project */ 25 | :root { 26 | --color-background: var(--vt-c-white); 27 | --color-background-soft: var(--vt-c-white-soft); 28 | --color-background-mute: var(--vt-c-white-mute); 29 | 30 | --color-border: var(--vt-c-divider-light-2); 31 | --color-border-hover: var(--vt-c-divider-light-1); 32 | 33 | --color-heading: var(--vt-c-text-light-1); 34 | --color-text: var(--vt-c-text-light-1); 35 | 36 | --section-gap: 160px; 37 | } 38 | 39 | @media (prefers-color-scheme: dark) { 40 | :root { 41 | --color-background: var(--vt-c-black); 42 | --color-background-soft: var(--vt-c-black-soft); 43 | --color-background-mute: var(--vt-c-black-mute); 44 | 45 | --color-border: var(--vt-c-divider-dark-2); 46 | --color-border-hover: var(--vt-c-divider-dark-1); 47 | 48 | --color-heading: var(--vt-c-text-dark-1); 49 | --color-text: var(--vt-c-text-dark-2); 50 | } 51 | } 52 | 53 | *, 54 | *::before, 55 | *::after { 56 | box-sizing: border-box; 57 | margin: 0; 58 | position: relative; 59 | font-weight: normal; 60 | } 61 | 62 | body { 63 | min-height: 100vh; 64 | color: var(--color-text); 65 | background: var(--color-background); 66 | transition: color 0.5s, background-color 0.5s; 67 | line-height: 1.6; 68 | font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, 69 | Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 70 | font-size: 15px; 71 | text-rendering: optimizeLegibility; 72 | -webkit-font-smoothing: antialiased; 73 | -moz-osx-font-smoothing: grayscale; 74 | } 75 | -------------------------------------------------------------------------------- /src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/main.css: -------------------------------------------------------------------------------- 1 | @import "./base.css"; 2 | 3 | #app { 4 | max-width: 1280px; 5 | margin: 0 auto; 6 | padding: 2rem; 7 | 8 | font-weight: normal; 9 | } 10 | 11 | a, 12 | .green { 13 | text-decoration: none; 14 | color: hsla(160, 100%, 37%, 1); 15 | transition: 0.4s; 16 | } 17 | 18 | @media (hover: hover) { 19 | a:hover { 20 | background-color: hsla(160, 100%, 37%, 0.2); 21 | } 22 | } 23 | 24 | @media (min-width: 1024px) { 25 | body { 26 | display: flex; 27 | place-items: center; 28 | } 29 | 30 | #app { 31 | display: grid; 32 | grid-template-columns: 1fr 1fr; 33 | padding: 0 2rem; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 41 | -------------------------------------------------------------------------------- /src/components/TheWelcome.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 80 | -------------------------------------------------------------------------------- /src/components/WelcomeItem.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 87 | -------------------------------------------------------------------------------- /src/components/icons/IconCommunity.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/components/icons/IconDocumentation.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/components/icons/IconEcosystem.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/components/icons/IconSupport.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/components/icons/IconTooling.vue: -------------------------------------------------------------------------------- 1 | 2 | 20 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import { createPinia } from 'pinia'; 3 | 4 | import App from './App.vue'; 5 | import router from './router'; 6 | 7 | import './assets/main.css'; 8 | 9 | const app = createApp(App); 10 | 11 | app.use(createPinia()); 12 | app.use(router); 13 | 14 | app.mount('#app'); 15 | -------------------------------------------------------------------------------- /src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from 'vue-router'; 2 | import HomeView from '../views/HomeView.vue'; 3 | 4 | const router = createRouter({ 5 | history: createWebHistory(import.meta.env.BASE_URL), 6 | routes: [ 7 | { 8 | path: '/', 9 | name: 'home', 10 | component: HomeView, 11 | }, 12 | { 13 | path: '/about', 14 | name: 'about', 15 | // route level code-splitting 16 | // this generates a separate chunk (About.[hash].js) for this route 17 | // which is lazy-loaded when the route is visited. 18 | component: () => import('../views/AboutView.vue'), 19 | }, 20 | { 21 | path: '/layout', 22 | name: '布局', 23 | component: () => import('../views/Layout.vue'), 24 | }, 25 | ], 26 | }); 27 | 28 | export default router; 29 | -------------------------------------------------------------------------------- /src/stores/counter.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | 3 | export const useCounterStore = defineStore({ 4 | id: 'counter', 5 | state: () => ({ 6 | counter: 0, 7 | }), 8 | getters: { 9 | doubleCount: state => state.counter * 2, 10 | }, 11 | actions: { 12 | increment() { 13 | this.counter++; 14 | }, 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /src/views/AboutView.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 16 | -------------------------------------------------------------------------------- /src/views/HomeView.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /src/views/Layout.vue: -------------------------------------------------------------------------------- 1 | 61 | 62 | 66 | 67 | 86 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": [ 4 | "env.d.ts", 5 | "src/**/*.ts", 6 | "src/**/*.tsx", 7 | "src/**/*.vue", 8 | "types/**/*.d.ts", 9 | "types/**/*.ts", 10 | "build/**/*.ts", 11 | "mock/**/*.ts", 12 | "vite.config.ts" 13 | ], 14 | "exclude": ["node_modules", "dist", "**/*.js"], 15 | "compilerOptions": { 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /types/auto-imports.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // noinspection JSUnusedGlobalSymbols 5 | // Generated by unplugin-auto-import 6 | export {} 7 | declare global { 8 | const EffectScope: typeof import('vue')['EffectScope'] 9 | const axios: typeof import('axios')['default'] 10 | const computed: typeof import('vue')['computed'] 11 | const createApp: typeof import('vue')['createApp'] 12 | const customRef: typeof import('vue')['customRef'] 13 | const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] 14 | const defineComponent: typeof import('vue')['defineComponent'] 15 | const effectScope: typeof import('vue')['effectScope'] 16 | const getCurrentInstance: typeof import('vue')['getCurrentInstance'] 17 | const getCurrentScope: typeof import('vue')['getCurrentScope'] 18 | const h: typeof import('vue')['h'] 19 | const inject: typeof import('vue')['inject'] 20 | const isProxy: typeof import('vue')['isProxy'] 21 | const isReactive: typeof import('vue')['isReactive'] 22 | const isReadonly: typeof import('vue')['isReadonly'] 23 | const isRef: typeof import('vue')['isRef'] 24 | const markRaw: typeof import('vue')['markRaw'] 25 | const nextTick: typeof import('vue')['nextTick'] 26 | const onActivated: typeof import('vue')['onActivated'] 27 | const onBeforeMount: typeof import('vue')['onBeforeMount'] 28 | const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] 29 | const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] 30 | const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] 31 | const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] 32 | const onDeactivated: typeof import('vue')['onDeactivated'] 33 | const onErrorCaptured: typeof import('vue')['onErrorCaptured'] 34 | const onMounted: typeof import('vue')['onMounted'] 35 | const onRenderTracked: typeof import('vue')['onRenderTracked'] 36 | const onRenderTriggered: typeof import('vue')['onRenderTriggered'] 37 | const onScopeDispose: typeof import('vue')['onScopeDispose'] 38 | const onServerPrefetch: typeof import('vue')['onServerPrefetch'] 39 | const onUnmounted: typeof import('vue')['onUnmounted'] 40 | const onUpdated: typeof import('vue')['onUpdated'] 41 | const provide: typeof import('vue')['provide'] 42 | const reactive: typeof import('vue')['reactive'] 43 | const readonly: typeof import('vue')['readonly'] 44 | const ref: typeof import('vue')['ref'] 45 | const resolveComponent: typeof import('vue')['resolveComponent'] 46 | const shallowReactive: typeof import('vue')['shallowReactive'] 47 | const shallowReadonly: typeof import('vue')['shallowReadonly'] 48 | const shallowRef: typeof import('vue')['shallowRef'] 49 | const toRaw: typeof import('vue')['toRaw'] 50 | const toRef: typeof import('vue')['toRef'] 51 | const toRefs: typeof import('vue')['toRefs'] 52 | const toValue: typeof import('vue')['toValue'] 53 | const triggerRef: typeof import('vue')['triggerRef'] 54 | const unref: typeof import('vue')['unref'] 55 | const useAttrs: typeof import('vue')['useAttrs'] 56 | const useCssModule: typeof import('vue')['useCssModule'] 57 | const useCssVars: typeof import('vue')['useCssVars'] 58 | const useDark: typeof import('@vueuse/core')['useDark'] 59 | const useLink: typeof import('vue-router')['useLink'] 60 | const useMouse: typeof import('@vueuse/core')['useMouse'] 61 | const useMyFetch: typeof import('@vueuse/core')['useFetch'] 62 | const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark'] 63 | const useRoute: typeof import('vue-router')['useRoute'] 64 | const useRouter: typeof import('vue-router')['useRouter'] 65 | const useSlots: typeof import('vue')['useSlots'] 66 | const useTitle: typeof import('@vueuse/core')['useTitle'] 67 | const watch: typeof import('vue')['watch'] 68 | const watchEffect: typeof import('vue')['watchEffect'] 69 | const watchPostEffect: typeof import('vue')['watchPostEffect'] 70 | const watchSyncEffect: typeof import('vue')['watchSyncEffect'] 71 | } 72 | // for type re-export 73 | declare global { 74 | // @ts-ignore 75 | export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue' 76 | import('vue') 77 | } 78 | // for vue template auto import 79 | import { UnwrapRef } from 'vue' 80 | declare module 'vue' { 81 | interface GlobalComponents {} 82 | interface ComponentCustomProperties { 83 | readonly EffectScope: UnwrapRef 84 | readonly axios: UnwrapRef 85 | readonly computed: UnwrapRef 86 | readonly createApp: UnwrapRef 87 | readonly customRef: UnwrapRef 88 | readonly defineAsyncComponent: UnwrapRef 89 | readonly defineComponent: UnwrapRef 90 | readonly effectScope: UnwrapRef 91 | readonly getCurrentInstance: UnwrapRef 92 | readonly getCurrentScope: UnwrapRef 93 | readonly h: UnwrapRef 94 | readonly inject: UnwrapRef 95 | readonly isProxy: UnwrapRef 96 | readonly isReactive: UnwrapRef 97 | readonly isReadonly: UnwrapRef 98 | readonly isRef: UnwrapRef 99 | readonly markRaw: UnwrapRef 100 | readonly nextTick: UnwrapRef 101 | readonly onActivated: UnwrapRef 102 | readonly onBeforeMount: UnwrapRef 103 | readonly onBeforeRouteLeave: UnwrapRef 104 | readonly onBeforeRouteUpdate: UnwrapRef 105 | readonly onBeforeUnmount: UnwrapRef 106 | readonly onBeforeUpdate: UnwrapRef 107 | readonly onDeactivated: UnwrapRef 108 | readonly onErrorCaptured: UnwrapRef 109 | readonly onMounted: UnwrapRef 110 | readonly onRenderTracked: UnwrapRef 111 | readonly onRenderTriggered: UnwrapRef 112 | readonly onScopeDispose: UnwrapRef 113 | readonly onServerPrefetch: UnwrapRef 114 | readonly onUnmounted: UnwrapRef 115 | readonly onUpdated: UnwrapRef 116 | readonly provide: UnwrapRef 117 | readonly reactive: UnwrapRef 118 | readonly readonly: UnwrapRef 119 | readonly ref: UnwrapRef 120 | readonly resolveComponent: UnwrapRef 121 | readonly shallowReactive: UnwrapRef 122 | readonly shallowReadonly: UnwrapRef 123 | readonly shallowRef: UnwrapRef 124 | readonly toRaw: UnwrapRef 125 | readonly toRef: UnwrapRef 126 | readonly toRefs: UnwrapRef 127 | readonly toValue: UnwrapRef 128 | readonly triggerRef: UnwrapRef 129 | readonly unref: UnwrapRef 130 | readonly useAttrs: UnwrapRef 131 | readonly useCssModule: UnwrapRef 132 | readonly useCssVars: UnwrapRef 133 | readonly useDark: UnwrapRef 134 | readonly useLink: UnwrapRef 135 | readonly useMouse: UnwrapRef 136 | readonly useMyFetch: UnwrapRef 137 | readonly usePreferredDark: UnwrapRef 138 | readonly useRoute: UnwrapRef 139 | readonly useRouter: UnwrapRef 140 | readonly useSlots: UnwrapRef 141 | readonly useTitle: UnwrapRef 142 | readonly watch: UnwrapRef 143 | readonly watchEffect: UnwrapRef 144 | readonly watchPostEffect: UnwrapRef 145 | readonly watchSyncEffect: UnwrapRef 146 | } 147 | } 148 | declare module '@vue/runtime-core' { 149 | interface GlobalComponents {} 150 | interface ComponentCustomProperties { 151 | readonly EffectScope: UnwrapRef 152 | readonly axios: UnwrapRef 153 | readonly computed: UnwrapRef 154 | readonly createApp: UnwrapRef 155 | readonly customRef: UnwrapRef 156 | readonly defineAsyncComponent: UnwrapRef 157 | readonly defineComponent: UnwrapRef 158 | readonly effectScope: UnwrapRef 159 | readonly getCurrentInstance: UnwrapRef 160 | readonly getCurrentScope: UnwrapRef 161 | readonly h: UnwrapRef 162 | readonly inject: UnwrapRef 163 | readonly isProxy: UnwrapRef 164 | readonly isReactive: UnwrapRef 165 | readonly isReadonly: UnwrapRef 166 | readonly isRef: UnwrapRef 167 | readonly markRaw: UnwrapRef 168 | readonly nextTick: UnwrapRef 169 | readonly onActivated: UnwrapRef 170 | readonly onBeforeMount: UnwrapRef 171 | readonly onBeforeRouteLeave: UnwrapRef 172 | readonly onBeforeRouteUpdate: UnwrapRef 173 | readonly onBeforeUnmount: UnwrapRef 174 | readonly onBeforeUpdate: UnwrapRef 175 | readonly onDeactivated: UnwrapRef 176 | readonly onErrorCaptured: UnwrapRef 177 | readonly onMounted: UnwrapRef 178 | readonly onRenderTracked: UnwrapRef 179 | readonly onRenderTriggered: UnwrapRef 180 | readonly onScopeDispose: UnwrapRef 181 | readonly onServerPrefetch: UnwrapRef 182 | readonly onUnmounted: UnwrapRef 183 | readonly onUpdated: UnwrapRef 184 | readonly provide: UnwrapRef 185 | readonly reactive: UnwrapRef 186 | readonly readonly: UnwrapRef 187 | readonly ref: UnwrapRef 188 | readonly resolveComponent: UnwrapRef 189 | readonly shallowReactive: UnwrapRef 190 | readonly shallowReadonly: UnwrapRef 191 | readonly shallowRef: UnwrapRef 192 | readonly toRaw: UnwrapRef 193 | readonly toRef: UnwrapRef 194 | readonly toRefs: UnwrapRef 195 | readonly toValue: UnwrapRef 196 | readonly triggerRef: UnwrapRef 197 | readonly unref: UnwrapRef 198 | readonly useAttrs: UnwrapRef 199 | readonly useCssModule: UnwrapRef 200 | readonly useCssVars: UnwrapRef 201 | readonly useDark: UnwrapRef 202 | readonly useLink: UnwrapRef 203 | readonly useMouse: UnwrapRef 204 | readonly useMyFetch: UnwrapRef 205 | readonly usePreferredDark: UnwrapRef 206 | readonly useRoute: UnwrapRef 207 | readonly useRouter: UnwrapRef 208 | readonly useSlots: UnwrapRef 209 | readonly useTitle: UnwrapRef 210 | readonly watch: UnwrapRef 211 | readonly watchEffect: UnwrapRef 212 | readonly watchPostEffect: UnwrapRef 213 | readonly watchSyncEffect: UnwrapRef 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /types/components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // Generated by unplugin-vue-components 5 | // Read more: https://github.com/vuejs/core/pull/3399 6 | export {} 7 | 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | AAlert: typeof import('ant-design-vue/es')['Alert'] 11 | ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb'] 12 | ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem'] 13 | AButton: typeof import('ant-design-vue/es')['Button'] 14 | ALayout: typeof import('ant-design-vue/es')['Layout'] 15 | ALayoutContent: typeof import('ant-design-vue/es')['LayoutContent'] 16 | ALayoutFooter: typeof import('ant-design-vue/es')['LayoutFooter'] 17 | ALayoutHeader: typeof import('ant-design-vue/es')['LayoutHeader'] 18 | ALayoutSider: typeof import('ant-design-vue/es')['LayoutSider'] 19 | AMenu: typeof import('ant-design-vue/es')['Menu'] 20 | AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] 21 | ASpace: typeof import('ant-design-vue/es')['Space'] 22 | ASpin: typeof import('ant-design-vue/es')['Spin'] 23 | ASubMenu: typeof import('ant-design-vue/es')['SubMenu'] 24 | DesktopOutlined: typeof import('@ant-design/icons-vue')['DesktopOutlined'] 25 | FileOutlined: typeof import('@ant-design/icons-vue')['FileOutlined'] 26 | HelloWorld: typeof import('./../src/components/HelloWorld.vue')['default'] 27 | IconCommunity: typeof import('./../src/components/icons/IconCommunity.vue')['default'] 28 | IconDocumentation: typeof import('./../src/components/icons/IconDocumentation.vue')['default'] 29 | IconEcosystem: typeof import('./../src/components/icons/IconEcosystem.vue')['default'] 30 | IconSupport: typeof import('./../src/components/icons/IconSupport.vue')['default'] 31 | IconTooling: typeof import('./../src/components/icons/IconTooling.vue')['default'] 32 | PieChartOutlined: typeof import('@ant-design/icons-vue')['PieChartOutlined'] 33 | RouterLink: typeof import('vue-router')['RouterLink'] 34 | RouterView: typeof import('vue-router')['RouterView'] 35 | TeamOutlined: typeof import('@ant-design/icons-vue')['TeamOutlined'] 36 | TheWelcome: typeof import('./../src/components/TheWelcome.vue')['default'] 37 | UserOutlined: typeof import('@ant-design/icons-vue')['UserOutlined'] 38 | WelcomeItem: typeof import('./../src/components/WelcomeItem.vue')['default'] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /types/global.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | declare global { 4 | type Recordable = Record; 5 | 6 | interface ViteEnv { 7 | VITE_APP_NODE_ENV?: string; 8 | VITE_PORT?: number; 9 | VITE_USE_MOCK?: boolean; 10 | VITE_USE_PWA?: boolean; 11 | VITE_USE_CDN?: boolean; 12 | VITE_USE_IMAGEMIN?: boolean; 13 | VITE_DROP_CONSOLE?: boolean; 14 | VITE_PROXY?: [string, string][]; 15 | VITE_GLOB_APP_TITLE?: string; 16 | VITE_GLOB_APP_SHORT_NAME?: string; 17 | VITE_GLOB_API_URL?: string; 18 | VITE_GLOB_API_URL_PREFIX?: string; 19 | VITE_BUILD_COMPRESS?: 'gzip' | 'brotli' | 'none'; 20 | VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE?: boolean; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url'; 2 | 3 | import type { UserConfig, ConfigEnv } from 'vite'; 4 | import { defineConfig, loadEnv } from 'vite'; 5 | import vue from '@vitejs/plugin-vue'; 6 | import vueJsx from '@vitejs/plugin-vue-jsx'; 7 | 8 | import { vitePluginConfig } from './build'; 9 | import { transformEnvConfType } from './build/utils'; 10 | import { createProxy } from './build/proxy'; 11 | 12 | // https://vitejs.dev/config/ 13 | export default defineConfig(({ mode }: ConfigEnv): UserConfig => { 14 | const root = process.cwd(); 15 | 16 | const viteEnv = transformEnvConfType(loadEnv(mode, root)); 17 | 18 | const { VITE_DROP_CONSOLE, VITE_PORT, VITE_PROXY } = viteEnv; 19 | 20 | return { 21 | plugins: [ 22 | vue({ include: [/\.vue$/, /\.md$/] }), 23 | vueJsx(), 24 | // ext vite plugin 25 | vitePluginConfig(viteEnv), 26 | ], 27 | resolve: { 28 | alias: { 29 | '@': fileURLToPath(new URL('./src', import.meta.url)), 30 | '#': fileURLToPath(new URL('./types', import.meta.url)), 31 | }, 32 | }, 33 | server: { 34 | https: false, 35 | // Listening on all local IPs 36 | host: true, 37 | port: VITE_PORT, 38 | // Load proxy configuration from .env 39 | proxy: createProxy(VITE_PROXY), 40 | }, 41 | esbuild: { 42 | // 移除日志打印及debugger 43 | drop: VITE_DROP_CONSOLE ? ['console', 'debugger'] : [], 44 | }, 45 | // 处理ant-design-vue 样式文件 46 | css: { 47 | preprocessorOptions: { 48 | less: { 49 | javascriptEnabled: true, 50 | }, 51 | }, 52 | }, 53 | // 依赖优化 - 预构建 54 | optimizeDeps: { 55 | include: ['vue', 'pinia', 'vue-router', 'ant-design-vue/es', '@vueuse/core'], 56 | }, 57 | }; 58 | }); 59 | --------------------------------------------------------------------------------