基于vue3语法糖完成axios的封装,把请求挂载到pinia上
pinia官网:pinia.vuejs.org/
pinia-plugin-persistedstate官网:prazdevs.github.io/pinia-plugi…
axios官网:www.axios-http.cn/
demo
安装
npm install pinia
npm i pinia-plugin-persistedstate
npm install axios
注册引入
在main.js文件中全局注册:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const app = createApp(App)
app.use(createPinia().use(piniaPluginPersistedstate))
app.mount('#app')
封装axios
在src/axios/request.js文件中:
// 将Axios封装成模块
import axios from 'axios'
import router from '@/router/index.js'
import { Toast } from '@/utils/extract'
import { useUserStore } from '@/stores/user'
// 创建axios实例
const request = axios.create({
baseURL: import.meta.env.VITE_API_URL, // api的base_url
timeout: 10000 // 请求超时时间
})
let store = null
let token
// 请求拦截器
request.interceptors.request.use(
(config) => {
// 可以在这里添加请求头等信息
// 登录后才挂载user🍍
if (!store) store = useUserStore()
token = store.token
if (token) {
// 判断是否存在token,如果存在的话,则每个http header都加上token
config.headers.Authorization = `Bearer ${token}` //请求头加上token
}
return config
},
(error) => {
// 请求错误处理
console.log(error) // for debug
Promise.reject(error)
}
)
// 响应拦截器
request.interceptors.response.use(
(response) => {
console.log(response)
if (response.status == 200) {
return response.data
} else {
router.push('/notFound')
}
},
(error) => {
// 对响应错误做处理
console.log('err' + error) // for debugd
Toast('服务器异常')
return Promise.reject(error)
}
)
export default request
在src/stores/user.js文件中:
import { ref, reactive } from 'vue'
import { defineStore } from 'pinia'
import { Toast, Toast_Success } from '@/utils/extract'
import request from '@/axios/request.js'
import router from '@/router/index.js'
export const useUserStore = defineStore(
'user',
() => {
const resp_signIn = reactive({})
const token = ref()
const isRemember = ref()
const userData = reactive({})
const resp_getUserInfo = reactive({})
// post登录
async function signIn(data) {
Object.assign(resp_signIn, await request.post('/onlineShop/signIn', data))
token.value = this.resp_signIn.data.token
isRemember.value = data.isRemember
if (this.resp_signIn.errCode == 1000) {
localStorage.setItem('token', this.resp_signIn.data.token)
Toast_Success('Successfully!')
// get用户信息
// 当获取token后,自动获取用户信息并保存在pinia中
if (localStorage.getItem('token') != null) {
Object.assign(
resp_getUserInfo,
await request.get('/onlineShop/getUserInfo', { params: {} })
)
Object.assign(userData, resp_getUserInfo.data)
}
router.push({
path: '/home'
})
} else {
Toast(this.resp_signIn.errMsg)
}
return token
}
// post注册
async function signUp(data) {
return await request.post('/onlineShop/signUp', data)
}
// get用户信息
async function getUserInfo() {
Object.assign(resp_getUserInfo, await request.get('/onlineShop/getUserInfo', { params: {} }))
Object.assign(userData, resp_getUserInfo.data)
}
// put更改用户信息
async function updateUserInfo(data) {
return await request.put('/onlineShop/updateUserInfo', data)
}
// post更改头像
const resp_uploadImage = reactive({})
async function uploadImage(data) {
Object.assign(resp_uploadImage, await request.post('/onlineShop/uploadImage', data))
}
// get验证码
const resp_getVerificationCode = reactive({})
async function getVerificationCode(data) {
Object.assign(
resp_getVerificationCode,
await request.get('/onlineShop/getVerificationCode', { params: { phoneNumber: data } })
)
return resp_getVerificationCode
}
return {
resp_signIn,
token,
isRemember,
signIn,
signUp,
userData,
resp_getUserInfo,
getUserInfo,
updateUserInfo,
resp_uploadImage,
uploadImage,
resp_getVerificationCode,
getVerificationCode
}
},
{
persist: true
}
)
在需要发送请求的vue文件中调用:
<-- 直接使用 -->
<div class="name">{{ userStore.userData.name }}</div>
import { useUserStore } from '@/stores/user'
// 接口
const userStore = useUserStore()
onBeforeMount(async () => {
// get用户信息
await userStore.getUserInfo()
if (userStore.userData.iconImage != '') {
originIcon.value = userStore.userData.iconImage
}
})
在请求还未完成时,有缓存的user信息在页面上显示;待到onBeforeMount生命周期内调用的请求完成,页面的信息便会更新
创建接口实例的时候,一定要在script部分的开头,不然会报错ReferenceError: Cannot access 'useUserStore' before initialization