在 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);
}
};