Vue3项目初始化搭建流程

269 阅读3分钟

基于Vue3.2+Vite+ts项目搭建

vite创建项目

Vite官方中文文档

Vite中的模块路径别名配置

  1. 在ts模块中加载node核心模块需要安装的node类型补充模块:npm i -D @typ/node
  2. vite.config.ts
  • import path from 'path'

  • image.png

  • tsconfig.json配置:"paths":{"@/*":["src/*"]}

代码规范和Eslint

安装Eslint文档

  1. 在package.json中"script"增加
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix"
  1. eslint默认vue2的验证规则,要更改配置文件。
//.eslintrc.js
module.exports = {
    extends:[
        'plugin:vue/vue3-strongly-recommended',
	'standard'
    ]
}
  1. 代码风格设置:standard
  2. vscode安装Volar插件
  3. 解决defineProps报错的问题

配置git commit hook

  • 在提交代码之前进行eslint校验git commit插件

  • 在package.json中配置

    lint=staged:{"*.{js,jsx,vue,ts,tsx}":["npm run lint","git add"]}

Git commit规范

Vue3中的Ts支持

要在单文件组件中使用 TypeScript,需要在<script>标签上加上 lang="ts"

初始化Vue Router

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

Vuex 是什么? | Vuex

Css

功能 {#features} | Vite中文网

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)
})

环境变量和模式

vite文档

.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/, '')
      }
    }
  }

生产环境