Vue在升级到3.0之后,我们不能再按照2.0的方式,在其原型链上封装第三方的插件对象。本文仿照Vuex的使用方法,结合Vue3.0的Composition API,实现一种在Vue 3.0下封装第三方插件的方法。
本文以封装Axios为例进行说明。
Vuex是通过use方法,注册全局对象。而其对象必须包括install方法,该方法会在use方法中被调用,完成全局内容的注册。
我们依照这个思路,定义一个AxiosPlugin类,在类内封装所有axios配置,包括基本配置,拦截器配置。该类包括install方法,在该方法中完成axios对象的全局注册。
// 新建axios目录下的index.js
import axios from 'axios'
import { inject, readonly } from 'vue'
class AxiosPlugin{
constructor(config){
this.config = config;
}
setRequestInterceptor = (instance) => {
instance.interceptors.request.use(
config => {
const token = localStorage.getItem('token');
if(token){
config.headers['token'] = token;
}
return config
},
err => Promise.reject(err)
);
return this;
}
setResponseInterceptor = (instance) => {
instance.interceptors.response.use(
res => res.data,
err => Promise.reject(err)
);
return this;
}
install(app, isReadonly = true){
let instance = axios.create(this.config);
this
.setRequestInterceptor(instance)
.setResponseInterceptor(instance);
app.provide("axios",
isReadonly ?
readonly(instance) : instance);
}
}
export function createAxios(config){
return new AxiosPlugin(config);
}
export function useAxios(){
const axiosInstance = inject('axios');
return axiosInstance;
}
export default createAxios({timeout:1000});
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axiosPlugin from '@/axios'
createApp(App).use(store).use(axiosPlugin).use(router).mount('#app');
// 在组件中使用axios对象
import { useAxios } from "@/axios"
export default {
name: 'FileUpload',
setup() {
const axios = useAxios();
return {};
}
}
</script>
注意,因为useAxios方法中包括Composition API inject,所以和useStore一样,必须在setup中直接调用,不能嵌套调用。