一、Vite简介
Vite 是一种新型前端构建工具,能够显著提升前端开发体验。7 月 13 日,Vite 3.0 正式发布。
去年 2 月,Vite 2 正式发布。从那时起,它的使用率不断增长,每周 npm 下载量超过 100 万次。发布后迅速形成了庞大的生态系统。Vite 正在推动 Web 框架的新一轮创新竞赛。
1、Vite 组成
它主要由两部分组成:
Vite 意在提供开箱即用的配置,同时它的 插件 API 和 JavaScript API 带来了高度的可扩展性,并有完整的类型支持。
2、浏览器支持
二、项目环境搭建
1、搭建项目
根据 Vite 官网介绍,可以使用 npm 或 yarn 或 pnmp 来初始化 Vite 项目。
兼容性注意 Vite 需要 Node.js 版本 >= 12.0.0。
本项目使用 pnpm 构建。
pnpm create vite
然后按照提示操作即可!
还可以通过附加的命令行选项直接指定项目名称和想要使用的模板。例如,要构建一个 Vite + Vue 项目,运行:
pnpm create vite vite3-vue3 -- --template vue
终端执行后:
项目目录结构:
安装依赖,运行后: 项目初始化完成!
2、集成 Vue-Router
Vue-Router 作为大多数项目必不可少的路由工具,已经被大多数的前端项目所使用,Vue-Router 可以让构建单页面应用变得更加的容易。
安装依赖
pnpm i vue-router@4
项目中配置
在 src 目录下创建一个文件夹 router/index.js,然后配置:
import { createRouter, createWebHashHistory } from 'vue-router'
import Layout from '@/layout'
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/Login.vue'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index.vue'),
meta: { title: 'Dashboard', elSvgIcon: 'Fold' }
}
]
},
]
const router = createRouter({
history: createWebHashHistory(),
scrollBehavior: () => ({ top: 0 }),
routes: constantRoutes
})
export default router
在 main.js 中引入
import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router'
const app = createApp(App)
app.use(router)
app.mount('#app')
3、集成 Pinia
Pinia 是 Vue 的存储库,它允许跨组件/页面共享状态。
集成操作可参考之前的文章 Pinia上手——Vue 存储库 。
安装依赖
pnpm i pinia
初始化
实现一个登录(login )请求。 创建一个 store/user.js 文件,添加如下代码:
import { loginAction } from '@/api/user'
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => {
return {
username: '',
avatar: ''
}
},
actions: {
update_username(username) {
this.$patch((state) => {
state.username = username
})
},
login(data) {
return new Promise((resolve, reject) => {
loginAction(data).then(res => {
if (res.code === 200) {
resolve(null)
} else {
reject(res)
}
}).catch((error) => {
reject(error)
})
})
}
}
})
挂载
在 main.js 中引入
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
4、集成 element-plus
安装依赖
pnpm i element-plus
用法
1、完整引入
如果对打包后的文件大小不是很在乎,那么使用完整导入会更方便。
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')
2、按需导入
自动导入
首先需要安装 unplugin-vue-components 和 unplugin-auto-import 这两款插件。
pnpm i -D unplugin-vue-components unplugin-auto-import
然后在 vite.config.js 中配置,代码如下:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
图标库配置
在 main.js 中引入如下代码:
import { createApp } from 'vue'
import App from './App.vue'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
5、配置 alias
在过去使用vue-cli的时候,一般使用 @ 去引入某些文件,由于 Vite 没有提供类似的配置,所以需要手动对其进行相关配置。
在 vite.config.js 中配置,代码如下:
import { defineConfig } from 'vite'
import path from 'path'
export default defineConfig({
define: {
'process.platform': null,
'process.version': null
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
})
三、数据请求
1、安装依赖
pnpm i axios
2、axios 请求封装
新建src/utils/request.js文件,代码如下:
import axios from 'axios'
import router from '@/router'
import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import { getToken } from '@/utils/auth'
import { useUserStore } from '@/store/user'
let reqConfig
let loadingE
const service = axios.create()
service.interceptors.request.use(
(request) => {
request.headers['AUTHORIZE_TOKEN'] = getToken()
if (request.isDownLoadFile) {
request.responseType = 'blob'
}
if (request.isUploadFile) {
request.headers['Content-Type'] = 'multipart/form-data'
}
reqConfig = request
if (request.bfLoading) {
loadingE = ElLoading.service({
lock: true,
text: '数据载入中',
background: 'rgba(0, 0, 0, 0.1)'
})
}
if (request.isParams) {
request.params = request.data
request.data = {}
}
return request
},
(err) => {
Promise.reject(err)
}
)
service.interceptors.response.use(
(res) => {
if (reqConfig.afHLoading && loadingE) {
loadingE.close()
}
if (reqConfig.isDownLoadFile) {
return res
}
const { code } = res.data
const successCode = '0,200,20000'
if (successCode.includes(code)) {
return res.data
} else {
return Promise.reject(res.data)
}
},
(err) => {
if (loadingE) loadingE.close()
ElMessage({
message: err,
type: 'error',
duration: 2 * 1000
})
const errObj = {
msg: err.toString(),
reqUrl: reqConfig.baseURL + reqConfig.url,
params: reqConfig.isParams ? reqConfig.params : reqConfig.data
}
return Promise.reject(JSON.stringify(errObj))
}
)
export function axiosReq({
url,
data,
method,
isParams,
bfLoading,
afHLoading,
isUploadFile,
isDownLoadFile,
baseURL
}) {
return service({
url: url,
method: method ?? 'get',
data: data ?? {},
isParams: isParams ?? false,
bfLoading: bfLoading ?? false,
afHLoading: afHLoading ?? true,
isUploadFile: isUploadFile ?? false,
isDownLoadFile: isDownLoadFile ?? false,
baseURL: baseURL ?? import.meta.env.VITE_APP_BASE_URL
})
}
export default request
3、处理请求
然后,在新建src/api/user.js,用来处理具体的网络请求。
import request from '@/utils/request'
export function loginAction(data) {
return request({
url: 'xxx',
data,
method: 'post'
})
}
|