在Vue 3中使用Vue.prototype或全局变量的方法

在Vue 3中使用Vue.prototype或全局变量的方法

技术背景

在Vue 2中,我们可以通过Vue.prototype添加全局属性或方法,这样在组件中就可以直接使用this来访问这些全局内容,避免了在每个组件中重复导入。但在Vue 3中,Vue.prototype不再适用,需要寻找新的方式来实现类似的全局变量使用。例如,我们想将Axios添加到全局,以便在组件中可以直接使用this.$axios来发起请求,而无需每次都导入Axios。

实现步骤

1. 使用provide/inject(适用于组合式API和选项式API)

提供(Provide)

在创建Vue应用时,使用provide方法将$axios提供给所有组件。示例代码如下:

1
2
3
4
5
6
import axios from 'axios';
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);
app.provide('$axios', axios); // 在应用创建时将$axios提供给所有组件

注入(Inject)

  • 组合式API
1
2
3
4
5
6
7
8
9
10
11
import { inject } from 'vue';

export default {
setup() {
const $axios = inject('$axios'); // 在需要使用的组件中注入$axios
// 可以使用$axios发起请求,例如 $axios.get(...)
return {
$axios
};
}
};
  • 选项式API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
export default {
inject: ['$axios'], // 在需要使用的组件中注入$axios
methods: {
fetchData() {
this.$axios.get('/api/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
}
}
};

2. 使用全局配置(仅适用于选项式API)

在创建Vue应用时,通过app.config.globalProperties来设置全局属性。示例代码如下:

1
2
3
4
5
6
7
8
import axios from 'axios';
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);
app.config.globalProperties.$axios = axios; // 设置全局属性$axios

app.mount('#app');

在选项式API的组件中,可以直接使用this.$axios

1
2
3
4
5
6
7
8
9
10
11
12
13
export default {
methods: {
fetchData() {
this.$axios.get('/api/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
}
}
};

3. 在setup函数中使用globalProperties(不推荐,可作为特殊情况的解决方案)

如果有库使用了globalProperties,并且需要在setup函数中访问它,可以使用getCurrentInstance。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<!-- 模板内容 -->
</template>

<script setup>
import { getCurrentInstance } from 'vue';

const app = getCurrentInstance();
const progressBar = app.appContext.config.globalProperties.$Progress;

progressBar.start();
</script>

核心代码

完整的应用创建和全局属性设置代码

1
2
3
4
5
6
7
8
9
import axios from 'axios';
import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);
app.provide('$axios', axios); // 使用provide/inject方式
app.config.globalProperties.$axios = axios; // 使用全局配置方式

app.mount('#app');

组件中使用provide/inject的组合式API代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { inject } from 'vue';

export default {
setup() {
const $axios = inject('$axios');
const fetchData = async () => {
try {
const response = await $axios.get('/api/data');
console.log(response.data);
} catch (error) {
console.error(error);
}
};

return {
fetchData
};
}
};

最佳实践

  • 优先使用provide/inject:它适用于组合式API和选项式API,并且更加灵活,可以在不同组件之间传递数据。
  • 使用全局配置时注意适用范围app.config.globalProperties仅适用于选项式API,在组合式API的setup函数中使用可能会导致代码混乱。
  • 避免在setup函数中过度使用globalProperties:这种方式可能被视为反模式,尽量使用provide/inject来替代。

常见问题

1. TypeScript报错

在使用app.config.globalProperties.$axios时,TypeScript可能会报错,提示Property '$axios' does not exist。解决方法是扩展ComponentCustomProperties接口,示例代码如下:

1
2
3
4
5
6
7
8
import axios from 'axios';
import { ComponentCustomProperties } from 'vue';

declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$axios: typeof axios;
}
}

2. 在组合式API的setup函数中使用globalProperties的问题

setup函数中使用globalProperties可能会导致代码的可维护性降低,因为它破坏了组合式API的响应式系统。建议尽量使用provide/inject来实现相同的功能。


在Vue 3中使用Vue.prototype或全局变量的方法
https://119291.xyz/posts/2025-04-14.how-to-use-vue-prototype-or-global-variable-in-vue3/
作者
ww
发布于
2025年4月14日
许可协议