├── .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 | 
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 | 
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 |
7 |
20 |
21 |
22 |
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 |
8 |
9 |
{{ msg }}
10 |
11 | You’ve successfully created a project with
12 | Vite + Vue 3 .
13 | What's next?
14 |
15 |
16 |
17 |
18 |
41 |
--------------------------------------------------------------------------------
/src/components/TheWelcome.vue:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Documentation
16 |
17 | Vue’s
18 | official documentation
19 | provides you with all information you need to get started.
20 |
21 |
22 |
23 |
24 |
25 |
26 | Tooling
27 |
28 | This project is served and bundled with
29 | Vite . The recommended IDE setup is
30 | VSCode +
31 | Volar . If you need to test your components and
32 | web pages, check out Cypress and
33 | Cypress Component Testing .
34 |
35 |
36 |
37 | More instructions are available in README.md
.
38 |
39 |
40 |
41 |
42 |
43 |
44 | Ecosystem
45 |
46 | Get official tools and libraries for your project:
47 | Pinia ,
48 | Vue Router ,
49 | Vue Test Utils , and
50 | Vue Dev Tools . If you need more resources, we
51 | suggest paying
52 | Awesome Vue
53 | a visit.
54 |
55 |
56 |
57 |
58 |
59 |
60 | Community
61 |
62 | Got stuck? Ask your question on
63 | Vue Land , our official Discord server, or
64 | StackOverflow . You should also
65 | subscribe to our mailing list and follow the official
66 | @vuejs
67 | twitter account for latest news in the Vue world.
68 |
69 |
70 |
71 |
72 |
73 |
74 | Support Vue
75 |
76 | As an independent project, Vue relies on community backing for its sustainability. You can help us by
77 | becoming a sponsor .
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/components/WelcomeItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
87 |
--------------------------------------------------------------------------------
/src/components/icons/IconCommunity.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/icons/IconDocumentation.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/icons/IconEcosystem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/icons/IconSupport.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/icons/IconTooling.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
18 |
19 |
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 |
2 |
3 |
This is an about page
4 |
5 |
6 |
7 |
16 |
--------------------------------------------------------------------------------
/src/views/HomeView.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/views/Layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Option 1
9 |
10 |
11 |
12 | Option 2
13 |
14 |
15 |
16 |
17 |
18 | User
19 |
20 |
21 | Tom
22 | Bill
23 | Alex
24 |
25 |
26 |
27 |
28 |
29 | Team
30 |
31 |
32 | Team 1
33 | Team 2
34 |
35 |
36 |
37 | File
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | User
46 | Bill
47 |
48 |
49 | Bill is a cat.
50 |
51 |
52 | Button
53 |
54 |
55 |
56 |
57 | Ant Design ©2018 Created by Ant UED
58 |
59 |
60 |
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 |
--------------------------------------------------------------------------------