在 Vue2 的时候我们如果想要设置一个全局数据通常都是在 Vue 的构造函数原型上增加属性:
import Vue from "vue";import App from "./App.vue";Vue.prototype.utils = {$http: function(){}};const app = new Vue({render: (h) => h(App)}).$mount("#app");console.log(app);
这样就把$http属性挂载到了 Vue 的构造函数上,又因为 Vue 的组件都是 Vue 构造函数的实例,所以组件内可以通过this访问组件的实例,顺着原型链就可以拿到$http。
export default {mounted(){// 可以获取到且正常执行!this.$http();}}
到了 Vue3 因为构造应用实例的方式不再使用 new 实例化的形式,所以 Vue3 提供了app.config.globalProperties让我们挂载全局的数据。
import { createApp } from "vue";import App from "./App.vue";const app = createApp(App);app.config.globalProperties.$http = function () {};app.mount("#app");
如果你在 Vue3 中使用选项式 API 仍然是可以通过this对象来访问到$http:
export default {mounted(){console.log(this.$http);}};
但如果你使用组合式 API 就不能使用this,而是使用getCurrentInstance()来获取当前组件的实例:
export default {setup() {const instance = getCurrentInstance();console.log(instance.proxy.$http);}};
:::warning
⚠️ 注意
虽然getCurrentInstance()能获取到组件的实例对象,但是 Vue 官方是不推荐我们使用的!!!所以更不要使用getCurrentInstance()来替代选项式 API 中的this!!!
:::
但是你会有疑问,能使用getCurrentInstance()获取到全局的数据,但是官方又不推荐使用,这不是很矛盾吗?
这其实app.config.globalProperties本身就不是给组合式 API 使用!!!
如果你真的使用组合式 API 又能使用全局数据,就可以使用 Vue 的依赖注入来实现:
import { createApp } from "vue";import App from "./App.vue";import globalProperties from "./globalProperties"const app = createApp(App);app.use(globalProperties)// app.config.globalProperties.$http = function () {};app.mount("#app");
export default {install(app) {app.provide("$http", function () {});}};
然后需要使用的地方使用inject()方法把数据进行注入:
import { inject } from "vue";export default {components: {GrandFather},setup() {// const instance = getCurrentInstance();// console.log(instance.proxy.$http);// 正常执行!!!const $http = inject("$http")console.log($http);}};
