在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);
|
注入(Inject)
1 2 3 4 5 6 7 8 9 10 11
| import { inject } from 'vue';
export default { setup() { const $axios = inject('$axios'); return { $axios }; } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export default { inject: ['$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;
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); 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
来实现相同的功能。