在 Vue2 的时候我们如果想要设置一个全局数据通常都是在 Vue 的构造函数原型上增加属性:

    1. import Vue from "vue";
    2. import App from "./App.vue";
    3. Vue.prototype.utils = {
    4. $http: function(){}
    5. };
    6. const app = new Vue({
    7. render: (h) => h(App)
    8. }).$mount("#app");
    9. console.log(app);

    这样就把$http属性挂载到了 Vue 的构造函数上,又因为 Vue 的组件都是 Vue 构造函数的实例,所以组件内可以通过this访问组件的实例,顺着原型链就可以拿到$http
    image.png

    1. export default {
    2. mounted(){
    3. // 可以获取到且正常执行!
    4. this.$http();
    5. }
    6. }

    到了 Vue3 因为构造应用实例的方式不再使用 new 实例化的形式,所以 Vue3 提供了app.config.globalProperties让我们挂载全局的数据。

    1. import { createApp } from "vue";
    2. import App from "./App.vue";
    3. const app = createApp(App);
    4. app.config.globalProperties.$http = function () {};
    5. app.mount("#app");

    如果你在 Vue3 中使用选项式 API 仍然是可以通过this对象来访问到$http:

    1. export default {
    2. mounted(){
    3. console.log(this.$http);
    4. }
    5. };

    但如果你使用组合式 API 就不能使用this,而是使用getCurrentInstance()来获取当前组件的实例:

    1. export default {
    2. setup() {
    3. const instance = getCurrentInstance();
    4. console.log(instance.proxy.$http);
    5. }
    6. };

    :::warning ⚠️ 注意
    虽然getCurrentInstance()能获取到组件的实例对象,但是 Vue 官方是不推荐我们使用的!!!所以更不要使用getCurrentInstance()来替代选项式 API 中的this!!! :::

    但是你会有疑问,能使用getCurrentInstance()获取到全局的数据,但是官方又不推荐使用,这不是很矛盾吗?
    这其实app.config.globalProperties本身就不是给组合式 API 使用!!!
    如果你真的使用组合式 API 又能使用全局数据,就可以使用 Vue 的依赖注入来实现:

    1. import { createApp } from "vue";
    2. import App from "./App.vue";
    3. import globalProperties from "./globalProperties"
    4. const app = createApp(App);
    5. app.use(globalProperties)
    6. // app.config.globalProperties.$http = function () {};
    7. app.mount("#app");
    1. export default {
    2. install(app) {
    3. app.provide("$http", function () {});
    4. }
    5. };

    然后需要使用的地方使用inject()方法把数据进行注入:

    1. import { inject } from "vue";
    2. export default {
    3. components: {
    4. GrandFather
    5. },
    6. setup() {
    7. // const instance = getCurrentInstance();
    8. // console.log(instance.proxy.$http);
    9. // 正常执行!!!
    10. const $http = inject("$http")
    11. console.log($http);
    12. }
    13. };