# vue3-pc-sys
**Repository Path**: yuyingqianduan/vue3-pc-sys
## Basic Information
- **Project Name**: vue3-pc-sys
- **Description**: Vue 3 + TypeScript + Vite4/5 + Ant-design-vue4.x+ Pinia + vue-router4搭建后台系统通用骨架
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-12-21
- **Last Updated**: 2024-01-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: vue3, TypeScript, CSS, ant-design-vue, Pinia
## README
# Vue 3 + TypeScript + Vite4/5 + Ant-design-vue4.x + Pinia + vue-router4
本项目采用前端最潮流技术搭建~仅供参考学习!
- Vue Language Features (Volar)
- TypeScript Vue Plugin (Volar)
## 前置知识
关于package.json里面,尖角号(^)和波浪线(~)的区别
- 尖角号(^)通常用于指定主要版本号不变,允许安装新的次要版本和修补程序版本
- 波浪线(~)通常用于指定包的修补程序版本不变,允许安装新的次要版本和主要版本
- /** */这种方式注释 则如果其他地方用到这个变量,鼠标放上去会有注释提示
- process.env.NODE_ENV 是node环境的变量
- 打印 process.env.NODE_ENV,值为 development 代表是开发环境,值为 production 代表是生产环境
## 创建项目
```shell
pnpm create vite [工程名] --template vue
```
### 重置样式表
方案一: css 重置样式表(Normalize.css)【推荐】
html 标签在浏览器中都有各自的默认样式,比如: p 标签有上下边距,strong 标签有字体加粗样式,em 标签有字体倾斜样式。不同浏览器的默认样式之间也会有差别,例如 ul 默认带有缩进的样式,在 IE 下,它的缩进是通过 margin 实现的,而 Firefox 下,它的缩进是由 padding 实现的。Normalize.css 不同浏览器默认样式的规范统一,从而提高开发效率。
- normalize.css 并不是简单的重置了所有的样式,保留标签语义化
- normalize 没有对所有标签采取一致的重置方式,而是有针对的修改,同时也保留了标签的语义化
- Normalize CSS 可以看成是一种 Reset CSS 的替代方案
```shell
pnpm install --save normalize.css
```
```js
// main.js引入
import 'normalize.css/normalize.css'
```
方案二:重置 CSS
[css reset](https://meyerweb.com/eric/tools/css/reset/)
总结:一般都是两个结合 起来处理
### vite4 别名处理
```shell
pnpm i vite-aliases -D
```
```ts
// vite.config.ts 使用
import { ViteAliases } from 'vite-aliases'
plugins: [ViteAliases()]
```
由于 vite-aliases 插件仅支持 ESM,需要在项目根路径下的 package.json 下配置如下代码
```json
{
"type": "module"
}
```
```shell
pnpm i @types/node -D
# 如果报错 降低版本 18.11.11
# @types/node 模块在我们使用 node 方法(比如 path.resolve)时提供 ts 类型声明,否则编辑器会报错,虽然不影响代码运行
```
tsconfig.json 需要额外配置
```json
"baseUrl": "./",
// paths安装了 vite-aliases依赖自动生成
```
## 采用 scss 预处理器
增加 -D 参数,在开发环境中才使用 sass,因为生产环境,scss 文件会被编译成 css 文件,这个插件是用不到的
```shell
pnpm install sass -D
```
## 在项目的根目录,新建 .nvmrc 文件,输入初始化时 node 的版本号,用来避免每次切换项目都手动切换 node 版本
新增此文件后需要重启 vscode,打开终端会自动切换 node 版本
.nvmrc 键入
v18
## 使用 polyfill
polyfill 是 web 项目兼容低版本浏览器的插件,安装 core-js 和 @vitejs/plugin-legacy
[@vitejs/plugin-legacy](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy)
```shell
pnpm i @vitejs/plugin-legacy -D
pnpm i core-js -S
# Terser must be installed because plugin-legacy uses Terser for minification
pnpm add -D terser
```
## 配置代码规范
### eslint 相关
- "off" 或 0 - 关闭规则
- "warn" 或 1 - 打开规则作为警告(不影响退出代码)
- "error" 或 2 - 打开规则作为错误(触发时退出代码为 1)
```shell
pnpm init @eslint/config
pnpm i @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-plugin-vue -D
```
在 package.json 的 script 中添加命令
```json
"scripts": {
"lint": "eslint --ext .ts,.vue,.js, --fix --quiet ./"
},
```
### Prettier 美化格式化代码
然后再根目录创建 .prettierrc.cjs 配置文件
```js
"lint:prettier": "prettier --write \"**/*.{js,ts,json,css,less,scss,vue,html,md}\""
```
```shell
pnpm i prettier -D
pnpm i eslint-config-prettier eslint-plugin-prettier -D
```
### ESLint + Prettier 参考配置
`pnpm eslint --init` 会自动生成 `.eslintrc.cjs` 或者 `pnpm init @eslint/config` 也会 会自动生成
```cjs
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:vue/vue3-essential',
'prettier', // 由于eslint和prettier都具备代码格式化的功能,并且可能出现冲突,所以继承eslint-config-prettier提供的配置,将eslint中冲突的配置项关闭了
'plugin:prettier/recommended'
],
overrides: [
{
env: {
node: true
},
files: ['.eslintrc.{js,cjs}'],
parserOptions: {
sourceType: 'script'
}
}
],
parserOptions: {
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: ['@typescript-eslint', 'vue', 'prettier'],
rules: {
// 开启这条规则后,会将prettier的校验规则传递给eslint,这样eslint就可以按照prettier的方式来进行代码格式的校验
'prettier/prettier': 'off',
// rules中添加prettier推荐配置
// 箭头函数体周围需要大括号
'arrow-body-style': 'off',
// 需要使用箭头函数进行回调
'prefer-arrow-callback': 'off',
// 不允许使用未声明的变量
'no-undef': 'error',
// 禁止未使用的变量
'no-unused-vars': 'error',
// 禁止使用 var
'no-var': 'error',
// 函数括号前的空格
'space-before-function-paren': 'off',
// 关闭名称校验
'vue/multi-word-component-names': 'off',
// 禁止 v-for 指令或范围属性的未使用变量定义 https://eslint.vuejs.org/rules/no-unused-vars.html
'vue/no-unused-vars': 'error',
// 禁止在与 v-for 相同的元素上使用 v-if https://eslint.vuejs.org/rules/no-use-v-if-with-v-for.html
'vue/no-use-v-if-with-v-for': [
'error',
{
allowUsingIterationVar: true
}
],
// 禁止未使用的变量 https://typescript-eslint.io/rules/no-unused-vars
'@typescript-eslint/no-unused-vars': 'error',
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
// 解决 Don't use `{}` as a type. `{}` actually means "any non-nullish value"
'@typescript-eslint/ban-types': [
'error',
{
extendDefaults: true,
types: {
'{}': false
}
}
],
// 解决使用 any 类型报错
'@typescript-eslint/no-explicit-any': ['off']
}
}
```
## 提交代码 使用 husky + lint-staged
```shell
pnpm i husky -D
pnpm i lint-staged -D
# 集成 husky 和 lint-staged 在项目根目录会自动生成 .husky/pre-commit 等文件 或者 npx husky-init
pnpx mrm@2 lint-staged
```
在 .gitignore 中增加 .eslintcache 不加这个,总是卡在提交哪一步
### 方式二
```shell
# 运行下面2条命令后也会在项目根目录创建 .husky 文件夹
pnpm pkg set scripts.prepare="husky install"
pnpm run prepare
# 给 Husky 添加一个 Hook
npx husky add .husky/pre-commit "npm run lint"
```
## 配置 ⽀持的浏览器 .browserslistrc 根目录
浏览器兼容性配置文件,可以配置支持那些浏览器 配置 cover 99.5% 或者 参考以下配置
> 1%
last 2 versions
not dead
not IE 11
## 自动修复 import 排序插件
eslint-plugin-simple-import-sort 自动修复 import 排序
```shell
pnpm i eslint-plugin-simple-import-sort -D
```
```js
// 在.eslintrc.cjs中配置
plugins:['simple-import-sort']
```
## 配置 EditorConfig
根目录配置 .editorconfig 文件
## 配置 stylelint
下载相关依赖
```shell
pnpm i stylelint stylelint-config-html stylelint-config-recommended-scss stylelint-config-recommended-vue stylelint-config-standard stylelint-config-standard-scss stylelint-config-recess-order postcss postcss-html postcss-lit stylelint-config-prettier stylelint-config-tailwindcss -D
```
stylelint-config-prettier 已经弃用 v15 [参考](https://stylelint.io/migration-guide/to-15)
命令执行完成后,如若报类似下面的警告,可以先不管
`unmet peer stylelint@“>= 11.x < 15”: found 16.0.2`
## commitizen 安装自动化提示工具
安装依赖
```shell
pnpm i @commitlint/cli @commitlint/config-conventional -D
# 安装自动化提示工具
pnpm i commitizen cz-conventional-changelog -D
pnpm i commitlint-config-cz cz-customizable -D
```
配置脚本命令
```json
{
"scripts": {
"commit": "git status && git add . && git-cz"
},
}
```
生成校验钩子
```shell
npx husky add .husky/commit-msg 'npx --no-install commitlint -e "$HUSKY_GIT_PARAMS"'
```
初始化命令行的选项信息 执行后会在package.json生成commitizen的配置信息
```shell
npx commitizen init cz-conventional-changelog --save-dev --save-exact
```
package.json 配置
```json
// 这里存在一个不足:无法正常校验通过命令行提交的类似 commit -m 'xxx'这样的备注信息
"config": {
"commitizen": {
"path": "./node_modules/cz-customizable"
},
"cz-customizable": {
"config": ".cz-config.cjs"
}
}
```
## tailwindcss 配置
```shell
pnpm install -D tailwindcss postcss autoprefixer
pnpx tailwindcss init
```
## vite多环境打包配置 根目录新建如下文件
- .env 全局默认配置文件,不论什么环境都会加载合并
- .env.development 开发环境下的配置文件
- .env.test 测试环境下的配置文件
- .env.stage 预发布环境下的配置文件
- .env.production 生产环境下的配置文件
解决 仅当 “--module” 选项为 “es2020”、“es2022”、“esnext”、“system”、“node16” 或 “nodenext” 时,才允许使用 “import.meta” 元属性。
tsconfig.json下配置
```json
"module" : "ESNext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
```
配置打包命令 package.json scripts
```json
"build:test": "vue-tsc && vite build --mode test ",
"build:stage": "vue-tsc && vite build --mode stage",
"build:prod": "vue-tsc && vite build --mode production",
```
## http-server 的使用
```shell
# 安装
pnpm install http-server -g
# 启动 任意一个文件夹都可以当服务器去使用 构建后我们一般在dist文件下执行
http-server
# 在当前目录下的 dist 下启动服务器,端口为 3000, 启动成功后打开默认浏览器,地址为:http://localhost:3000/
http-server './dist/' -p 3000 -o
```
## 打包分析插件
打包后,会在根目录下生成一个 stats.html文件,用浏览器打开后即可看到打包情况
```shell
pnpm install rollup-plugin-visualizer -D
```
```ts
// vite.config.js
import { defineConfig } from 'vite'
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [visualizer()]
})
```
## 通过监听文件修改,自动重启 vite 服务
最常用的场景就是监听 vite.config.js 和 .env.development 文件,修改 vite 配置文件和环境配置文件,是需要重启 vite 才会生效,通过这个插件,在修改上述两个文件则不需要重新运行
```shell
pnpm i vite-plugin-restart -D
```
```ts
// vite.config.js
import ViteRestart from 'vite-plugin-restart'
export default {
plugins: [
ViteRestart({
restart: [
'vite.config.js',
]
})
],
};
```
## 配置pinia,并做持久化存储
```shell
pnpm i pinia -S
pnpm i pinia-plugin-persist -S
```
## 项目中 svg 统一处理
因为svg图标在任何设备下都可以高清显示,不会模糊 这就是理由
- height=“1em” width=“1em” 可以方便地通过设置父元素的font-size属性控制尺寸
- fill=“currentColor” 可以方便地根据父元素或自身的color属性控制颜色
[iconfont 阿里巴巴图表库](https://www.iconfont.cn/)
```html
icon: https://www.test.com + '/icons/test.svg'
```
```shell
pnpm i vite-plugin-svg-icons -D
```
```ts
// vite.config.ts
import {createSvgIconsPlugin} from 'vite-plugin-svg-icons';
import { defineConfig,loadEnv } from 'vite'
import {createSvgIconsPlugin} from 'vite-plugin-svg-icons';
const path = require("path");
export default ({ mode }) => defineConfig({
plugins: [
vue(),
createSvgIconsPlugin({
// 指定要缓存的文件夹
iconDirs: [resolve(process.cwd(), 'src/assets/svg')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]'
})
]
})
// 更多配置说明
viteSvgIcons({
// 指定图标文件夹,数组形式,可以有多个
iconDirs: [path.resolve(process.cwd(), 'icons')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
// 自定义插入位置
inject?: 'body-last' | 'body-first',
// 设置图标样式类名
className?: 'svg-icon',
// 设置svg元素属性
svgoOptions: {},
// 指定标题内容
title?: false,
// 生成sprite
svgSprite: false,
// 导入图标接口
runtimeIconImport: 'import-all' | 'async',
})
```
```ts
// main.ts
import 'virtual:svg-icons-register'
```
```html
```
封装 svg组件
```html
```
svg 组件全局引入使用
```ts
// main.ts
// 在main.js中加入
import svgIcon from '~components/SvgIcon/index.vue'
createApp(App).component('svg-icon', svgIcon)
// 页面中使用
// 控制大小
```
如果需要改变svg的颜色只需要把svg自带的fill去掉即可!
## setup语法糖name增强,使vue3语法糖支持name属性
vue3语法糖默认是没有name属性的,在我们使用 keep-alive 的时候需要用到 name
```shell
pnpm i vite-plugin-vue-setup-extend -D
```
```ts
// vite.config.ts
import { defineConfig} from 'vite'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
export default ({ mode }) => defineConfig({
plugins: [
vueSetupExtend()
]
}
// 组件使用
```
## 需要配置代理的情况
浏览器的同源策略限制了前端页面向不同域名的接口发起请求,这导致某些情况下需要使用代理服务器来转发请求
- 使用第三方 API 或服务:例如,使用第三方地图 API 服务,需要向 API 服务提供商的域名下的接口发起请求,而这与前端页面所在的域名不同
- 开发环境与生产环境不同:在开发环境中,前端页面通常运行在本地的开发服务器上,而后端服务则运行在远程服务器上。在这种情况下,由于开发服务器与后端服务器的域名不同,因此需要使用代理服务器将请求转发到正确的后端服务端点
- 部分接口需要登录认证:在某些情况下,服务端需要对接口进行访问控制,需要用户先在页面进行登录认证。这时,前端页面需要先向自己的域名下的登录接口发起请求进行认证,获得认证信息后,再使用代理服务器将包含认证信息的请求转发到相应的接口上
- token的校验 Authorization: 'Bearer ' + token
## 图片资源压缩
```shell
pnpm i vite-plugin-imagemin -D
```
```ts
// vite.config.ts
import viteImagemin from 'vite-plugin-imagemin'
plugin: [
viteImagemin({
gifsicle: {
optimizationLevel: 7,
interlaced: false
},
optipng: {
optimizationLevel: 7
},
mozjpeg: {
quality: 20
},
pngquant: {
quality: [0.8, 0.9],
speed: 4
},
svgo: {
plugins: [
{
name: 'removeViewBox'
},
{
name: 'removeEmptyAttrs',
active: false
}
]
}
})
]
```
## 安装UI库 ant-design-vue
[ant-design-vue官方文档](https://www.antdv.com/docs/vue/getting-started-cn)
```shell
# 安装
pnpm i --save ant-design-vue@4.x
## 图标
pnpm install --save @ant-design/icons-vue
# 自动按需引入组件
pnpm install unplugin-vue-components -D
```
## 配置进度条 nprogress
```shell
pnpm i nprogress -S
pnpm i @types/nprogress -D
```
## 封装 axios
```shell
pnpm i axios -S
pnpm i qs -S
```
## 安装路由
```shell
pnpm add vue-router@4
#OR
pnpm i vue-router@4 -S
#CDN
```
## 安装动画css animate.css 库
[animate.css 官网](https://animate.style/)
```shell
pnpm install animate.css --save
# 使用
animate__animated + 动画类名
```
## 记录问题
- Q: 类型"ImportMeta"上不存在属性"env"
- A: 在tsconfig.json文件的"compilerOptions"里添加 "types": ["vite/client"]
- Q: vue3有好用的hooks么
- A: 有,推荐[vueuse中文文档参考](https://www.vueusejs.com/guide/),[vueuse英文文档参考](https://vueuse.org/guide/)
- Q: 有时候 node_modules 删不掉什么办法强制移除node_modules
- A: 当前项目执行 Remove-item -Force -Recurse node_modules 即可快速删除 或者 安装`npm install rimraf -g` 执行名,rimraf node_modules
- Q: 规则@tailwind css未知(unknownAtRules)
- A: .vscode 文件夹下 配置 settings.json:`"files.associations": { "*.css": "tailwindcss"}` 即可解决
- Q: vue3使用scss ::v-deep深度选择器抛出如下警告:`usage as a combinator has been deprecated. Use :deep() instead.`
- A: :deep(.xxx选择器/类名){} 即可解决
- Q: TS 去写项目代码一个没有类型声明的 npm 包 / 模块的时候 `Cannot find module or its corresponding type declarations`
- A: 方式一粗暴:注释TS检测 @ts-ignore,方式二:新建一个 XXX.d.ts 文件 declare module 'xxxx'
- Q: a-form-item 使用prop 校验控制台报错 `prop` is deprecated. Please use `name` instead.
- A: 按照推荐使用 name 即可 无需prop
- Q: async await 报错 `Property 'result' does not exist on type 'AxiosResponse'`
- A: 代码如下拓展出来对应的属性即可
```js
declare module 'axios' {
interface AxiosResponse {
// 这个地方为AxiosResponse添加扩展属性
code: number
result: string
message: string | undefined | null
data: T
}
}
```