pnpm官网:https://www.pnpm.cn/
1 安装
npm
npm install -g pnpm # 或 npm install -g @pnpm/exe
version
> pnpm -v
8.9.2
2 创建项目
# pnpm create vite
pnpm create vite vite3-vue3 -- --template vue
cd <Project name>
pnpm install
pnpm run dev
3 集成 Vue-Router
pnpm i vue-router@4
router/index.js
import { createRouter, createWebHashHistory } from 'vue-router'
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/Login.vue'),
hidden: true
},
]
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')
4 集成 Pinia
Pinia 是 Vue 的存储库,它允许跨组件/页面共享状态
安装
pnpm i pinia
5 页面
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 './style.css'
import App from './App.vue'
import router from '@/router'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(router)
app.use(createPinia())
app.mount('#app')
6 配置 alias
在过去使用vue-cli的时候,一般使用 @ 去引入某些文件,由于 Vite 没有提供类似的配置,所以需要手动对其进行相关配置
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
define: {
// path库报错修复
'process.platform': null,
'process.version': null
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
})
7 封装数据请求
安装
pnpm i axios
utils/request.js
import axios from 'axios'
import {getMemberToken} from "@/utils/auth.js";
import {message} from 'ant-design-vue';
import {ref} from 'vue';
let reqConfig
let loadingE
const service = axios.create()
// 请求拦截
service.interceptors.request.use(
(request) => {
// token setting
request.headers['Authorization'] = "Bearer " + getMemberToken()
/* download file*/
if (request.isDownLoadFile) {
request.responseType = 'blob'
}
/* upload file*/
if (request.isUploadFile) {
request.headers['Content-Type'] = 'multipart/form-data'
}
reqConfig = request
if (request.bfLoading) {
const content = ref('Loading...');
loadingE = message.loading({content: () => content.value});
setTimeout(() => {
content.value = 'Loaded!';
}, 1000);
}
/*
*params会拼接到url上
* */
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 则,会放回到请求方法中.then ,返回的res为 undefined
return Promise.reject(res.data)
}
},
(err) => {
/*http错误处理*/
if (loadingE) loadingE.close()
const content = ref('Loading...');
loadingE = message.loading({content: () => content.value});
setTimeout(() => {
content.value = 'Loaded!';
}, 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 request({
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
api/user.js
import request from '@/utils/request'
export function loginUrlApi() {
return request({
url: '/wx/api/v1/member/loginUrl',
isParams: true,
data: {
url: encodeURIComponent(
window.location.href
)
}
})
}
8 集成 ant
安装
pnpm install ant-design-vue
如果要使用其中的图标功能,还需要额外安装一个依赖
pnpm install @ant-design/icons-vue
按需加载
pnpm install unplugin-vue-components -D
vite.config.js
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import Components from "unplugin-vue-components/vite";
import {AntDesignVueResolver} from "unplugin-vue-components/resolvers";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
Components({
resolvers: [
AntDesignVueResolver({
importStyle: "less"
})
],
// 解决组件命名冲突问题
directoryAsNamespace: true
}),
],
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
modifyVars: {
"@primary-color": "#0083FF"
}
}
}
},
define: {
// path库报错修复
'process.platform': null,
'process.version': null
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
server: {
proxy: {
'/wx/api': {
target: 'http://127.0.0.1:7201',
changeOrigin: true,
rewrite: path => path.replace(RegExp(`^api`), '')
},
}
}
})