兼容性注意:Vite 需要 Node.js 版本 >= 12.0.0。
在创建项目文件目录下打开 cmd 运行以下命令
# npm 6.x
npm init @vitejs/app projectName --template
# npm 7+, 需要额外的双横线:
npm init @vitejs/app projectName -- --template
# yarn
yarn create @vitejs/app projectName --template
![image.png](https://img-blog.csdnimg.cn/img_convert/3fdcd50f85a804bd3269078d84618c4c.png#clientId=uf30abecb-412b-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=462&id=u60e33100&margin=[object Object]&name=image.png&originHeight=808&originWidth=1653&originalType=binary&ratio=1&rotation=0&showTitle=false&size=121990&status=done&style=none&taskId=ub2a8537f-3a3b-48e3-95f7-161add8ae64&title=&width=944.5714285714286)
//yarn
yarn add sass --dev
//npm
npm i sass -D
就直接使用了,不用像webpack 还要安装sass-loader
//npm
npm install vue-router
//yarn
yarn add vue-router
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'Login',
component: () => import('xxxx'), // 注意这里要带上 文件后缀.vue
},
]
const router = createRouter({
history: createWebHistory(),
routes,
})
export default router
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
const app = createApp(App)
//链式
app.use(router).mount('#app')
yarn add axios
npm i axios -S
在 src 文件下新增 utils 文件夹,service.ts 和 request.ts
![image.png](https://img-blog.csdnimg.cn/img_convert/03eb23b3bde02518e69bcc5bbf970e4f.png#clientId=u1e499d95-2955-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=387&id=u75ec5e02&margin=[object Object]&name=image.png&originHeight=678&originWidth=490&originalType=binary&ratio=1&rotation=0&showTitle=false&size=39460&status=done&style=none&taskId=u6643d583-8108-4fd6-a658-2927af6bc04&title=&width=280)
/**
* axios 请求配置
*/
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElNotification } from 'element-plus'
/**
* 请求失败后的错误统一处理
* @param status 请求失败的状态码
*/
const errorHandle = (status: number) => {
// 状态码判断
switch (status) {
case 302: ElNotification.error('接口重定向了!');
break;
case 400:
ElNotification.error("发出的请求有错误,服务器没有进行新建或修改数据的操作==>" + status)
break;
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401: //重定向
ElNotification.error("token:登录失效==>" + status)
break;
// 403 token过期
// 清除token并跳转登录页
case 403:
ElNotification.error("登录过期,用户得到授权,但是访问是被禁止的==>" + status)
break;
case 404:
ElNotification.error("网络请求不存在==>" + status)
break;
case 406:
ElNotification.error("请求的格式不可得==>" + status)
break;
case 408: ElNotification.error(" 请求超时!")
break;
case 410:
ElNotification.error("请求的资源被永久删除,且不会再得到的==>" + status)
break;
case 422:
ElNotification.error("当创建一个对象时,发生一个验证错误==>" + status)
break;
case 500:
ElNotification.error("服务器发生错误,请检查服务器==>" + status)
break;
case 502:
ElNotification.error("网关错误==>" + status)
break;
case 503:
ElNotification.error("服务不可用,服务器暂时过载或维护==>" + status)
break;
case 504:
ElNotification.error("网关超时==>" + status)
break;
default:
ElNotification.error("其他错误错误==>" + status)
}
}
//axios创建实例
const service = axios.create({
//默认地址
baseURL: "",
// baseURL: "",
//请求超时时间
timeout: 3000,
//配置请求头
headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;' }
});
// 请求拦截器
service.interceptors.request.use((config:AxiosRequestConfig) => {
//处理业务代码 ex:是否存在token
return config
}, (error) => {
// 错误抛到业务代码
error.data = {}
error.data.msg = '服务器异常,请联系管理员!'
return Promise.resolve(error)
})
//响应拦截器
service.interceptors.response.use((response: AxiosResponse) => {
const status = response.status
if (status < 200 || status >= 300) {
// 处理http错误,抛到业务代码
errorHandle(status)
}
return response
}, (error) => {
// 错误抛到业务代码
error.data = {}
error.data.msg = '请求超时或服务器异常,请检查网络或联系管理员!'
return Promise.resolve(error)
})
export default service
/**
* request 请求封装
*/
import service from "./service"
export default {
get(url: string, data = {}) {
return new Promise((resolve, reject) => {
service
.get(url, { params: data })
.then(response => {
resolve(response.data);
})
.catch(err => {
reject(err);
});
});
},
delete(url: string, data = {}) {
return new Promise((resolve, reject) => {
service
.delete(url, { params: data })
.then(response => {
resolve(response.data);
})
.catch(err => {
reject(err);
});
});
},
post(url: string, data = {}) {
return new Promise((resolve, reject) => {
service
.post(url, data)
.then(response => {
resolve(response.data);
})
.catch(err => {
reject(err);
});
});
},
put(url: string, data = {}) {
return new Promise((resolve, reject) => {
service
.put(url, data)
.then(response => {
resolve(response.data);
})
.catch(err => {
reject(err);
});
});
}
}
以后发送请求就直接使用,request.ts
//NPM
$ npm install element-plus --save
// Yarn
$ yarn add element-plus
import { createApp } from 'vue'
import App from './App.vue'
//引用element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(ElementPlus).mount('#app')
npm install pinia --save
yarn add pinia
/**
* pinia 创建
*/
import { createPinia } from 'pinia'
const store = createPinia()
export default store
import { createApp } from 'vue'
import App from './App.vue'
//引入pinia
import store from './store'
const app = createApp(App)
app.use(store).mount('#app')
可以直接复制使用,额外的配置可以自定义。
备注可以信息用不到的,可以删除。
//需要分别安装这两个插件
npm install @types/node --save-dev
//使用 vite-plugin-compression 可以 gzip 或 brotli 的方式来压缩资源,这一步需要服务器端的配合,vite 只能帮你打包出 .gz 文件。此插件使用简单,你甚至无需配置参数,引入即可。
//开启 gzip 可以极大的压缩静态资源,对页面加载的速度起到了显著的作用。
npm install vite-plugin-compression --save-dev
import { defineConfig } from 'vite' // 帮手函数,这样不用 jsdoc 注解也可以获取类型提示
import vue from '@vitejs/plugin-vue' //识别.vue文件
import viteCompression from "vite-plugin-compression"; //gzip必备插件,开启gzip、br压缩
//path
const path = require('path');
/**
*
* 此时 TS 可能有这个错误提示:找不到模块“path”或其相应的类型声明。
* 解决方法:npm install @types/node --save-dev
*/
const resolve = (dir: string) => path.join(__dirname, dir)//__dirname 总是指向被执行 js 文件的绝对路径 EX:/d1/d2/myscript.js 文件中写了 __dirname, 它的值就是 /d1/d2
// https://vitejs.dev/config/
export default defineConfig({
//开发或生产环境服务的公共基础路径
base: './',
//作为静态资源服务的文件夹。并在构建期间复制到 outDir 的根目录,并且始终按原样提供或复制而无需进行转换。
publicDir: "public",
//用于加载 .env 文件的目录。
// envDir:"root",
//控制台输出的级别 info 、warn、error、silent
logLevel: "info",
// 设为false 可以避免 vite 清屏而错过在终端中打印某些关键信息
clearScreen: true,
//plugins配置需要使用的插件列表
plugins: [vue(), viteCompression({
verbose: true,
disable: false,
threshold: 10240,
algorithm: "gzip",
ext: ".gz",
})],
// 路径相关规则
resolve: {
//配置别名
alias: {
'@': resolve('src'),// @表示当前的src目录路径
comps: resolve('src/components'),// comps表示当前的src目录路径下components
apis: resolve('src/apis'),// apis表示当前的src目录路径下apis
views: resolve('src/views'),
utils: resolve('src/utils'),
routes: resolve('src/routes'),
}
},
//配置全局css变量
// css: {
// preprocessorOptions: {
// scss: {
// additionalData: '@import "@/assets/styles/mixin.scss";',//多个全局样式直接分号引用就行了
// },
// },
// },
//本地运行配置,以及反向代理配置
// server: {
// host: "0.0.0.0",//指定服务器应该监听哪个 IP 地址。 如果将此设置为 0.0.0.0 或者 true 将监听所有地址,包括局域网和公网地址。
// port: 12138,//指定开发服务器端口
// strictPort: false, //设为true时端口被占用则直接退出,不会尝试下一个可用端口
// https: false,//是否启用 http 2
// open: true,//服务启动时自动在浏览器中打开应用
// cors: true,//为开发服务器配置 CORS , 默认启用并允许任何源
// force: true,//是否强制依赖预构建
// hmr: false,//禁用或配置 HMR 连接
// // 传递给 chockidar 的文件系统监视器选项
// watch: {
// ignored: ["!**/node_modules/your-package-name/**"]
// },
// // 反向代理配置
// proxy: {
// '/api': {
// target: "https://xxxx.com/",// 所要代理的目标地址
// changeOrigin: true,
// rewrite: (path) => path.replace("/^/api /", '') //重写地址
// }
// }
// },
//打包配置
build: {
//传递给 Terser 的更多 minify 选项。 生产环境去除 console debugger
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
// //浏览器兼容性 "esnext"|"modules"
// target: "modules",
// //指定输出路径
// outDir: "dist",
// //生成静态资源的存放路径
// assetsDir: "assets",
// //小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项
// assetsInlineLimit: 4096,
// //启用/禁用 CSS 代码拆分
// cssCodeSplit: true,
// //构建后是否生成 source map 文件
// sourcemap: false,
// //自定义底层的 Rollup 打包配置
// rollupOptions: {
// },
// //@rollup/plugin-commonjs 插件的选项
// commonjsOptions: {
// },
// //构建的库
// lib: {
// },
// //当设置为 true,构建后将会生成 manifest.json 文件
// manifest: false,
// // 设置为 false 可以禁用最小化混淆,
// // 或是用来指定使用哪种混淆器
// // boolean | 'terser' | 'esbuild'
// minify: "terser", //terser 构建后文件体积更小
// //设置为 false 来禁用将构建后的文件写入磁盘
// write: true,
// //默认情况下,若 outDir 在 root 目录下,则 Vite 会在构建时清空该目录。
// emptyOutDir: true,
// //启用/禁用 brotli 压缩大小报告
// brotliSize: true,
// //chunk 大小警告的限制
// chunkSizeWarningLimit: 500
},
})
/***
* 注意事项:
*/
// ● 假设不配置 base 时,打包之后,访问时出现白屏。
// ● alias 不配置的时候,每次引入文件需要找根目录,比较麻烦。
项目根目录分别新建:.env 、.env.development 、.env.production
![image.png](https://img-blog.csdnimg.cn/img_convert/a31b12abd9e72a0c1a6f5425128f2f01.png#clientId=u6dd3eca0-f03e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=338&id=u2cae385e&margin=[object Object]&name=image.png&originHeight=592&originWidth=487&originalType=binary&ratio=1&rotation=0&showTitle=false&size=41425&status=done&style=none&taskId=u4ebc535f-6edf-4b35-8447-211b5879f84&title=&width=278.2857142857143)
# port 端口号
VITE_PORT = 8888
# open 运行 npm run dev 时自动打开浏览器
VITE_OPEN = false
# public path 配置线上环境路径(打包)、本地通过 http-server 访问时,请置空即可
VITE_PUBLIC_PATH = ''
# 本地环境
ENV = 'development'
# 本地环境接口地址
VITE_API_URL = 'http://localhost:8888/'
# 线上环境
ENV = 'production'
# 线上环境接口地址
VITE_API_URL = 'URL'
使用:
console.log(import.meta.env.VITE_API_URL)
//输入命令 npm run dev 系统会识别.env.developmen文件下的VITE_API_URL地址
//输入命令 npm run build 系统会识别.env.production文件下的VITE_API_URL地址
# eslint 安装
yarn add eslint --dev
# eslint 插件安装
yarn add eslint-plugin-vue --dev
yarn add @typescript-eslint/eslint-plugin --dev
yarn add eslint-plugin-prettier --dev
# typescript parser
yarn add @typescript-eslint/parser --dev
注意: 如果 eslint 安装报错:
可以尝试运行以下命令:
yarn config set ignore-engines true
//配置 eslint 校验规则:
module.exports = {
root: true,
env: {
browser: true,
node: true,
es2021: true,
},
parser: 'vue-eslint-parser',
extends: [
'eslint:recommended',
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
// eslint-config-prettier 的缩写
'prettier',
],
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
// eslint-plugin-vue @typescript-eslint/eslint-plugin eslint-plugin-prettier的缩写
plugins: ['vue', '@typescript-eslint', 'prettier'],
rules: {
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'vue/multi-word-component-names': 'off',
'no-var': 'error',
'prettier/prettier': 'error',
// 禁止出现console
'no-console': 'warn',
// 禁用debugger
'no-debugger': 'warn',
// 禁止出现重复的 case 标签
'no-duplicate-case': 'warn',
// 禁止出现空语句块
'no-empty': 'warn',
// 禁止不必要的括号
'no-extra-parens': 'off',
// 禁止对 function 声明重新赋值
'no-func-assign': 'warn',
// 禁止在 return、throw、continue 和 break 语句之后出现不可达代码
'no-unreachable': 'warn',
// 强制所有控制语句使用一致的括号风格
curly: 'warn',
// 要求 switch 语句中有 default 分支
'default-case': 'warn',
// 强制尽可能地使用点号
'dot-notation': 'warn',
// 要求使用 === 和 !==
eqeqeq: 'warn',
// 禁止 if 语句中 return 语句之后有 else 块
'no-else-return': 'warn',
// 禁止出现空函数
'no-empty-function': 'warn',
// 禁用不必要的嵌套块
'no-lone-blocks': 'warn',
// 禁止使用多个空格
'no-multi-spaces': 'warn',
// 禁止多次声明同一变量
'no-redeclare': 'warn',
// 禁止在 return 语句中使用赋值语句
'no-return-assign': 'warn',
// 禁用不必要的 return await
'no-return-await': 'warn',
// 禁止自我赋值
'no-self-assign': 'warn',
// 禁止自身比较
'no-self-compare': 'warn',
// 禁止不必要的 catch 子句
'no-useless-catch': 'warn',
// 禁止多余的 return 语句
'no-useless-return': 'warn',
// 禁止变量声明与外层作用域的变量同名
'no-shadow': 'off',
// 允许delete变量
'no-delete-var': 'off',
// 强制数组方括号中使用一致的空格
'array-bracket-spacing': 'warn',
// 强制在代码块中使用一致的大括号风格
'brace-style': 'warn',
// 强制使用骆驼拼写法命名约定
camelcase: 'warn',
// 强制使用一致的缩进
indent: 'off',
// 强制在 JSX 属性中一致地使用双引号或单引号
// 'jsx-quotes': 'warn',
// 强制可嵌套的块的最大深度4
'max-depth': 'warn',
// 强制最大行数 300
// "max-lines": ["warn", { "max": 1200 }],
// 强制函数最大代码行数 50
// 'max-lines-per-function': ['warn', { max: 70 }],
// 强制函数块最多允许的的语句数量20
'max-statements': ['warn', 100],
// 强制回调函数最大嵌套深度
'max-nested-callbacks': ['warn', 3],
// 强制函数定义中最多允许的参数数量
'max-params': ['warn', 3],
// 强制每一行中所允许的最大语句数量
'max-statements-per-line': ['warn', { max: 1 }],
// 要求方法链中每个调用都有一个换行符
'newline-per-chained-call': ['warn', { ignoreChainWithDepth: 3 }],
// 禁止 if 作为唯一的语句出现在 else 语句中
'no-lonely-if': 'warn',
// 禁止空格和 tab 的混合缩进
'no-mixed-spaces-and-tabs': 'warn',
// 禁止出现多行空行
'no-multiple-empty-lines': 'warn',
// 禁止出现;
semi: ['warn', 'never'],
// 强制在块之前使用一致的空格
'space-before-blocks': 'warn',
// 强制在 function的左括号之前使用一致的空格
// 'space-before-function-paren': ['warn', 'never'],
// 强制在圆括号内使用一致的空格
'space-in-parens': 'warn',
// 要求操作符周围有空格
'space-infix-ops': 'warn',
// 强制在一元操作符前后使用一致的空格
'space-unary-ops': 'warn',
// 强制在注释中 // 或 /* 使用一致的空格
// "spaced-comment": "warn",
// 强制在 switch 的冒号左右有空格
'switch-colon-spacing': 'warn',
// 强制箭头函数的箭头前后使用一致的空格
'arrow-spacing': 'warn',
'prefer-const': 'warn',
'prefer-rest-params': 'warn',
'no-useless-escape': 'warn',
'no-irregular-whitespace': 'warn',
'no-prototype-builtins': 'warn',
'no-fallthrough': 'warn',
'no-extra-boolean-cast': 'warn',
'no-case-declarations': 'warn',
'no-async-promise-executor': 'warn',
},
globals: {
defineProps: 'readonly',
defineEmits: 'readonly',
defineExpose: 'readonly',
withDefaults: 'readonly',
},
}
# eslint 忽略检查 (根据项目需要自行添加)
*.sh
node_modules
lib
*.md
*.scss
*.woff
*.ttf
.vscode
.idea
dist
mock
public
bin
build
config
index.html
src/assets
# 安装 prettier
yarn add prettier --dev
module.exports = {
tabWidth: 2,
jsxSingleQuote: true,
jsxBracketSameLine: true,
printWidth: 100,
singleQuote: true,
semi: false,
overrides: [
{
files: '*.json',
options: {
printWidth: 200,
},
},
],
arrowParens: 'always',
}
# 忽略格式化文件 (根据项目需要自行添加)
node_modules
dist
{
"script": {
//添加以下这两个
"lint": "eslint src --fix --ext .ts,.tsx,.vue,.js,.jsx",
"prettier": "prettier --write ."
}
}
解决 ESLint 中的样式规范和 prettier 中样式规范的冲突,以 prettier 的样式规范为准,使 ESLint 中的样式规范自动失效
yarn add eslint-config-prettier --dev
上面配置完成后,可以运行以下命令测试下代码检查个格式化效果:
# eslint 检查
npm run lint or -yarn lint
# prettier 自动格式化
npm run prettier or -yarn prettier