Skip to content

Commit 42467cb

Browse files
authored
Merge pull request #117 from probil/feature/multiple-versions-support
Feature/multiple versions support
2 parents 9c52792 + 38d633a commit 42467cb

File tree

2 files changed

+150
-31
lines changed

2 files changed

+150
-31
lines changed

README.md

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
A small wrapper for integrating axios to Vuejs
1010

11-
## Why
11+
## Why
1212

1313
I created this library because, in the past, I needed a simple solution to migrate from `vue-resource` to `axios`.
1414

@@ -96,7 +96,7 @@ export default {
9696

9797
however, in composition API `setup` we can't use `this`, you should use `provide` API to share the globally instance properties first, then use `inject` API to inject `axios` to `setup`:
9898

99-
```js
99+
```ts
100100
// main.ts
101101
import { createApp } from 'vue'
102102
import App from './App.vue'
@@ -130,4 +130,79 @@ export default {
130130
}
131131
```
132132

133-
Please kindly check full documention of [axios](https://github.com/axios/axios) too
133+
Please kindly check full documentation of [axios](https://github.com/axios/axios) too
134+
135+
## Multiple axios instances support
136+
137+
The library allows to have different version of axios at the same time as well as change the default registration names (e.g. `axios` and `$http`). To use this feature you need to provide options like an object where:
138+
- `<key>` is registration name
139+
- `<value>` is instance of axios
140+
141+
For Vue it looks like this:
142+
```js
143+
// Vue 2 / Vue 3 + Composition API
144+
import App from './App.vue'
145+
import VueAxios from 'vue-axios'
146+
import axios from 'axios'
147+
import axios2 from 'axios'
148+
Vue.use(VueAxios, { $myHttp: axios, axios2: axios2 }) // or app.use() for Vue 3 Optiona API
149+
150+
// usage
151+
export default {
152+
methods: {
153+
getList(){
154+
this.$myHttp.get(api).then((response) => {
155+
console.log(response.data)
156+
})
157+
this.axios2.get(api).then((response) => {
158+
console.log(response.data)
159+
})
160+
}
161+
}
162+
}
163+
```
164+
It works similarly in Options API of Vue 3 but if you want to use Composition API you should adjust your code a bit to extract proper keys, e.g.:
165+
```ts
166+
// Vue 2 + Setup function
167+
import { createApp } from 'vue'
168+
import App from './App.vue'
169+
import store from './store'
170+
import axios from 'axios'
171+
import VueAxios from 'vue-axios'
172+
173+
const app = createApp(App).use(store)
174+
app.use(VueAxios, { $myHttp: axios, axios2: axios2 })
175+
app.provide('$myHttp', app.config.globalProperties.$myHttp) // provide '$myHttp'
176+
app.provide('axios2', app.config.globalProperties.axios2) // provide 'axios2'
177+
app.mount('#app')
178+
179+
// App.vue
180+
import { inject } from 'vue'
181+
182+
export default {
183+
name: 'Comp',
184+
setup() {
185+
const $myHttp: any = inject('$myHttp') // inject $myHttp
186+
187+
const getListWithMyHttp = (): void => {
188+
$myHttp
189+
.get(api)
190+
.then((response: { data: any }) => {
191+
console.log(response.data)
192+
});
193+
};
194+
195+
const axios2: any = inject('axios2') // inject axios2
196+
const getListWithAxios2 = (): void => {
197+
axios2
198+
.get(api)
199+
.then((response: { data: any }) => {
200+
console.log(response.data)
201+
});
202+
};
203+
204+
205+
return { getListWithMyHttp, getListWithAxios2 }
206+
}
207+
}
208+
```

src/index.js

Lines changed: 72 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,30 @@
11
/**
22
* Install plugin
33
* @param app
4-
* @param axios
4+
* @param {axios|Record<string:axios>}options
55
*/
6-
function plugin(app, axios) {
6+
function plugin(app, options) {
77
if (plugin.installed) {
88
return;
99
}
1010

11-
if (!axios) {
12-
console.error('You have to install axios');
11+
const normalizedConfig = isAxiosLike(options) ? migrateToMultipleInstances(options) : options;
12+
if (!isValidConfig(normalizedConfig)) {
13+
console.error('[vue-axios] configuration is invalid, expected options are either <axios_instance> or { <registration_key>: <axios_instance> }');
1314
return;
1415
}
1516

1617
plugin.installed = true;
1718

18-
if (app.version && app.version.split('.')[0] < 3) {
19-
Object.defineProperties(app.prototype, {
20-
21-
axios: {
22-
get: function get() {
23-
return axios;
24-
}
25-
},
26-
27-
$http: {
28-
get: function get() {
29-
return axios;
30-
}
31-
}
32-
33-
});
34-
} else if (app.version && app.version.split('.')[0] >= 3) {
35-
app.config.globalProperties.axios = axios;
36-
app.config.globalProperties.$http = axios;
37-
} else {
38-
console.error('Unknown Vue version');
19+
const vueVersion = getVueVersion(app);
20+
if (!vueVersion) {
21+
console.error('[vue-axios] unknown Vue version');
3922
return;
4023
}
41-
42-
app.axios = axios;
43-
app.$http = axios;
24+
const handler = vueVersion < 3 ? registerOnVue2 : registerOnVue3;
25+
Object.keys(normalizedConfig).forEach(registrationKey => {
26+
handler(app, registrationKey, normalizedConfig[registrationKey])
27+
})
4428
}
4529

4630
if (typeof exports == "object") {
@@ -52,3 +36,63 @@ if (typeof exports == "object") {
5236
}
5337

5438
export default plugin;
39+
40+
/**
41+
* @param {Vue} app
42+
* @param {string} key
43+
* @param {axios} axiosInstance
44+
* @returns {void}
45+
*/
46+
function registerOnVue2(app, key, axiosInstance) {
47+
Object.defineProperty(app.prototype, key, {
48+
get() {
49+
return axiosInstance
50+
}
51+
})
52+
app[key] = axiosInstance;
53+
}
54+
55+
/**
56+
* @param {Vue} app
57+
* @param {string} key
58+
* @param {axios} axiosInstance
59+
* @returns {void}
60+
*/
61+
function registerOnVue3(app, key, axiosInstance) {
62+
app.config.globalProperties[key] = axiosInstance;
63+
app[key] = axiosInstance;
64+
}
65+
66+
/**
67+
* @param {axios|Record<string|axios>}obj
68+
* @returns {boolean}
69+
*/
70+
function isAxiosLike(obj) {
71+
return obj && typeof obj.get === 'function' && typeof obj.post === 'function'
72+
}
73+
74+
/**
75+
* Migrates previous configuration to support multiple instances
76+
* @param axiosInstance
77+
* @returns {Record<string, axios>}
78+
*/
79+
function migrateToMultipleInstances(axiosInstance) {
80+
return {
81+
axios: axiosInstance,
82+
$http: axiosInstance,
83+
}
84+
}
85+
86+
function isValidConfig(config) {
87+
if (typeof config !== 'object') return false
88+
return Object.keys(config).every(key => isAxiosLike(config[key]))
89+
}
90+
91+
/**
92+
* Return Vue version as a number
93+
* @param {Vue} app
94+
* @returns {?number}
95+
*/
96+
function getVueVersion (app) {
97+
return app && app.version && Number(app.version.split('.')[0])
98+
}

0 commit comments

Comments
 (0)