安装Vite
npm init vite@latest
安装eslint
npm install eslint --save-dev
npx eslint --init (初始化eslint配置)
添加 npm script 验证脚本
"scripts": {
...
"lint": "eslint src/**/*.{js,jsx,vue,ts,tsx} --fix",
}
编辑器集成eslint
- 禁用Vetur
- 安装eslint插件
- 安装Volar插件
配置 git commit hook
npx mrm@2 lint-staged
- https://github.com/okonet/lint-staged
在commit之前 对代码进行校验
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
"npm run lint",
// "git add" 之前的版本需要手动把 lint 过程中修改的代码手动 add,新版本不需要了
]
}
vite-plugin-eslint
npm install vite-plugin-eslint --save-dev
- vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import eslintplugin from 'vite-plugin-eslint'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(),eslintplugin({'配置参数'})]
})
commit 提交规范
Commit message 和 Change log 编写指南
Install commitlint
Vue3 ts支持
- vue文件添加ts声明
vue3中ts相关写法
Vue3 中的
单独一个组件文件 text.tsx
//函数式组件
export default () => {
return (
text函数式组件
)
}
//需要有状态的组件 options API
import { defineComponent } from '@vue/runtime-core'
export default defineComponent({
props:{
msg:{
type:String
}
},
render(){
return (
{ this.msg }
)
}
})
//需要有状态的组件 组合式 API
import { defineComponent,ref } from '@vue/runtime-core'
interface PropsType {
msg:string
}
export default defineComponent({
props:{
msg:{
type:String
}
},
setup(){
const count = ref (0)
return (props:PropsType ) => (
{props.msg}
{count}
)
}
})
初始化VueRouter
- 安装vue-router
npm install vue-router@4
// src\router\index.ts
import { createRouter, RouteRecordRaw, createWebHashHistory } from 'vue-router'
const routes: RouteRecordRaw[] = [
{
path: '/',
component: () => import('../views/home/index.vue')
},
{
path: '/login',
component: () => import('../views/login/index.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
// src\main.ts
import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
createApp(App).use(router).mount('#app')
初始化 Vuex
- 安装Vuex
npm install vuex@next --save
// src\store\index.ts
import { createStore } from 'vuex'
const store = createStore({
state: {},
getters: {},
mutations: {},
actions: {},
modules: {}
})
export default store
// src\main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App)
.use(router)
.use(store)
.mount('#app')
usestore-组合式函数类型声明
结合ts优化后
//store/index.ts
import { createStore, useStore as baseUseStore, Store } from 'vuex'
import { InjectionKey } from 'vue'
export interface State {
count: number
}
// 定义 injection key
export const key: InjectionKey> = Symbol('store')
export const store = createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++
}
}
})
// 定义自己的 `useStore` 组合式函数 //调用该 useStore 可以推断出state属性及类型
export function useStore() {
return baseUseStore(key)
}
export default store
// vuex.d.ts
import { ComponentCustomProperties } from 'vue'
import { Store } from 'vuex'
import { State } from './store/index'
declare module '@vue/runtime-core' {
// 声明自己的 store state
// interface State {
// count: number
// }
// 为 `this.$store` 提供类型声明
interface ComponentCustomProperties {
$store: Store
}
}
配置模块路径别名
vite不自带@等路径别名
import xxx from '@/views/xxx.vue' //不支持src别名@符 所以要手动配置
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 注意:在 ts 模块中加载 node 核心模块需要安装 node 的类型补充模块:npm i -D @types/node
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
...
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
})
// tsconfig.json
//所有以@开头的都指向src
{
"compilerOptions": {
...
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
...
}
使用
// js
import xxx from '@/api/xxx.ts'
// html
// css
@import url("@/styles/index.scss");
background: url("@/assets/logo.png");
CSS样式管理
vite css配置 文档
Vite 也同时提供了对 .scss, .sass, .less, .styl 和 .stylus 文件的内置支持。没有必要为它们安装特定的 Vite 插件,但必须安装相应的预处理器依赖:
# .scss and .sass
npm install -D sass
# .less
npm install -D less
# .styl and .stylus
npm install -D stylus
如果是用的是单文件组件,可以通过
要想在全局单文件中不用单独引入就可以使用scss全局变量 需要配置使用全局样式
配置使用全局样式变量
css-preprocessoroptions
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx({
// 配置选项
})
],
resolve: {
alias: {
'@': path.join(__dirname, 'src')//绝对路径
}
},
css: {
preprocessorOptions: {
// 给 sass-loader 传递选项
sass: {
// @/ 是 src/ 的别名
// 所以这里假设你有 `src/variables.sass` 这个文件
// 注意:在 sass-loader v8 中,这个选项名是 "prependData"
additionalData: `@import "@/styles/variables.scss"`
},
// 默认情况下 `sass` 选项会同时对 `sass` 和 `scss` 语法同时生效
// 因为 `scss` 语法在内部也是由 sass-loader 处理的
// 但是在配置 `prependData` 选项的时候
// `scss` 语法会要求语句结尾必须有分号,`sass` 则要求必须没有分号
// 在这种情况下,我们可以使用 `scss` 选项,对 `scss` 语法进行单独配置
scss: {
additionalData: `@import "~@/variables.scss";`
},
// 给 less-loader 传递 Less.js 相关选项
less: {
// http://lesscss.org/usage/#less-options-strict-units `Global Variables`
// `primary` is global variables fields name
globalVars: {
primary: '#fff'
}
}
}
}
})
自动注册全局组件
glob-impor
全局组件放在 components 目录下
- components
+ foo
+ index.vue
+ index.ts
+ bar
+ index.vue
+ index.ts
- main.ts
// main.ts
const app = createApp(App)
const modules = import.meta.globEager('./components/**/index.ts')
for (const path in modules) {
app.use(modules[path].default)
}
// components/foo/index.ts
import { App } from '@vue/runtime-dom'
import Component from './index.vue'
export default {
install (app: App) {
app.component('Foo', Component)
}
}
// components/bar/index.ts
import { App } from '@vue/runtime-dom'
import Component from './index.vue'
export default {
install (app: App) {
app.component('Bar', Component)
}
}
服务端交互
**基于axios封装请求模块
- 安装axios
npm i axios
基础配置
//src/utils/request.ts
import axios from 'axios'
const request = axios.create({
baseURL: '' //基础请求路径
})
// 请求拦截器
request.interceptors.request.use(
config => {
// 统一设置用户身份 Token
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
request.interceptors.response.use(
response => {
// 统一处理响应错误,例如 token 无效、服务端异常等
return response
},
err => {
return Promise.reject(err)
}
)
export default request
/**
* 公共基础接口封装
*/
import request from '@/utils/request'
export const getLoginInfo = () => {
return request({
method: 'GET',
url: '/login/info'
})
}
/**
* 组件中使用
*/
import { getLoginInfo } from '@/api/common'
import { onMounted } from '@vue/runtime-core'
onMounted(() => {
getLoginInfo().then(res => {
console.log(res)
})
})
多环境 baseURL
环境变量和模式
# .env.development
# 开发模式下加载的环境变量
VITE_API_BASEURL=http://a.com
# .env.production
# 生产模式下加载的环境变量
VITE_API_BASEURL=http://b.com
// src\utils\request.ts
const request = axios.create({
// localhost:8080/xxx
// abc.com/xxx
// test.com/xxx
baseURL: import.meta.env.VITE_API_BASEURL
})
//env.d.ts中对类型声明
///
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
interface ImportMetaEnv {
VITE_API_BASEURL: string
// 更多环境变量...
}
跨域问题
推荐方案
- 开发环境
- 在服务端配置 CORS。
- 配置开发服务器代理,比如 vite-server.proxy。
- 生产环境
- 在服务端配置 CORS。
- 配置生产服务器代理,比如 nginx。
CORS
CORS 全称为 Cross Origin Resource Sharing(跨域资源共享)。这种方案对于前端来说没有什么工作量,和正常发送请求写法上没有任何区别,工作量基本都在后端(其实也没啥工作量,就是配置一些 HTTP 协议)。
- 跨源资源共享(CORS)
- 跨域资源共享 CORS 详解
服务器代理
可能有些后端开发人员觉得配置 CORS 麻烦不想搞,那纯前端也是有解决方案的。
在开发模式下可以下使用开发服务器的 proxy 功能,比如 vite - server.proxy。
但这种方法在生产环境是不能使用的。在生产环境中需要配置生产服务器(比如 nginx、Apache 等)进行反向代理。在本地服务和生产服务配置代理的原理都是一样的,通过搭建一个中转服务器来转发请求规避跨域的问题。
//vite.config.ts
export default defineConfig({
server: {
proxy: {
// 字符串简写写法
'/foo': 'http://localhost:4567',
// 选项写法
'/api': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
},
// 正则表达式写法
'^/fallback/.*': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/fallback/, '')
},
// 使用 proxy 实例
'/api': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
configure: (proxy, options) => {
// proxy 是 'http-proxy' 的实例
}
}
}
}
})
初始化 Element Plus
npm install element-plus --save
Element Plus快速开始