基于Vue3.2+Vite+ts项目搭建
vite创建项目
Vite中的模块路径别名配置
- 在ts模块中加载node核心模块需要安装的node类型补充模块:
npm i -D @typ/node - 在
vite.config.ts:
-
import path from 'path' -
-
在
tsconfig.json配置:"paths":{"@/*":["src/*"]}
代码规范和Eslint
安装Eslint文档
- 在package.json中"script"增加
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix"
- eslint默认vue2的验证规则,要更改配置文件。
//.eslintrc.js
module.exports = {
extends:[
'plugin:vue/vue3-strongly-recommended',
'standard'
]
}
- 代码风格设置:standard
- vscode安装Volar插件
- 解决defineProps报错的问题
配置git commit hook
-
在提交代码之前进行eslint校验git commit插件
-
在package.json中配置
lint=staged:{"*.{js,jsx,vue,ts,tsx}":["npm run lint","git add"]}
Git commit规范
- 阮一峰的git commit message
- 强制验证commit message的插件commitlint
Vue3中的Ts支持
要在单文件组件中使用 TypeScript,需要在
<script>标签上加上lang="ts"
初始化Vue Router
- /src/router/index.ts
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
//routes接口RouteRecordRaw
const routes:RouteRecordRaw[] = [
{
path: '/',
name: 'home',
component: () => import('../components/Home/index.vue')
}, {
path: '/login',
name: 'login',
component: () => import('../components/Login/index.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
初始化Vuex
Css
- css.preprocessorOptions配置加载全局变量
export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: '@import "@/styles/index.scss"'//引入全局变量所在路径
}
}
}
})
与服务端进行交互
axios的二次封装
官方文档Axios
import axios from 'axios'
//创建axios实列
const request = axios.create({
baseURL: ''
})
// 添加请求拦截器
request.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error)
})
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error)
})
接口类型处理
import request from '@/utils/request'
interface ResponseData<T = any> {
status:number,
msg:string,
data:T
}
//调用.get方法增加请求数据接口范型
export const getList = () => {
return request.get<ResponseData<{
age:number,
slide:string[]
}>>('/login/data')
}
将api的eslint驼峰校验取消
overrides: [
{
files: ['src/api/**/*.ts'],
rules: {
camelcase: 'off'
}
}
]
响应拦截器统一处理
处理登录过期和请求失败
// 控制登录过期的锁
let isRefreshing = false
// 响应拦截器
request.interceptors.response.use(function (response) {
const status = response.data.status
// 正确的情况
if (!status || status === 200) {
return response
}
// 错误情况:比如 token 无效...
// 统一处理登录过期
if (status === 410000) {
if (isRefreshing) return Promise.reject(response)
isRefreshing = true
ElMessageBox.confirm('您的登录已过期,您可以取消停留在此页面,或确认重新登录', '登录过期', {
confirmButtonText: '确认',
cancelButtonText: '取消'
}).then(() => {
// 清除本地过期的登录状态
store.commit('setUser', null)
// 跳转到登录页面
router.push({
name: 'login',
query: {
redirect: router.currentRoute.value.fullPath
}
})
// 抛出异常
}).finally(() => {
isRefreshing = false
})
// 在内部消化掉这个业务异常
return Promise.reject(response)
}
// 其它错误情况
ElMessage.error(response.data.msg || '请求失败,请稍后重试')
// 手动返回一个 Promise 异常
return Promise.reject(response)
}, function (error) {
ElMessage.error(error.message || '请求失败,请稍后重试')
return Promise.reject(error)
})
请求拦截器统一处理
统一添加token字段
// login/index.vue
// 存储登录用户信息
store.commit('setUser', {
...data.user_info,
token: data.token
})
// utils/request.ts
// 请求拦截器
request.interceptors.request.use(function (config) {
// 统一设置用户身份 token
const user = store.state.user
if (user && user.token) {
config.headers.Authorization = `Bearer ${user.token}`
}
return config
}, function (error) {
// Do something with request error
return Promise.reject(error)
})
环境变量和模式
.env.development
#开发模式下加载的环境变量
VITE_API_BASEURL=https://shop.fed.lagou.com/api/admin/
.env.d.ts
// eslint-disable-next-line no-unused-vars
interface ImportMetaEnv {
VITE_API_BASEURL: string
// 更多环境变量...
}
跨域处理
开发环境
- 后端开启cors
- 前端配置proxy服务器代理。vite中的server-proxy
server: {
proxy: {
// 字符串简写写法
// /foo/123 => http://localhost:4567/foo/123
// '/foo': 'http://localhost:4567/foo',
// 选项写法
'/admin': {
// /admin/login => https://shop.fed.lagou.com/api/admin/login
target: 'https://shop.fed.lagou.com/api', // 代理的目标地址
// 兼容基于名字的虚拟主机
// a.com localhost:xxx
// b.com localhost:xxx
// HTTP 请求头部的 origin 字段
// 我们在开发模式:默认的 origin 是真实的 origin:localhost:3000
// changeOrigin: true,代理服务会把 origin 修改为目标地址 http://jsonplaceholder.typicode.com
changeOrigin: true
// 路径重写
// http://jsonplaceholder.typicode.com/api/xxx
// /api/xxx => http://jsonplaceholder.typicode.com/api/xxx
// http://jsonplaceholder.typicode.com/xxx
// /api/xxx => http://jsonplaceholder.typicode.com/api/xxx
// rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
生产环境
- nginx 推荐文章