vue3使用全局扩展属性app.config.globalProperties

前言

在最近的开发中,发现了这种用法,目前并不明确这种有多少副作用,这里只做记录,因此,可能存在大量官网描述。

官网的说明

这是对 Vue 2 中 Vue.prototype 使用方式的一种替代,此写法在 Vue 3 已经不存在了。与任何全局的东西一样,应该谨慎使用。如果全局属性与组件自己的属性冲突,组件自己的属性将具有更高的优先级。

TS与选项式api中

某些插件会通过 app.config.globalProperties 为所有组件都安装全局可用的属性。举例来说,我们可能为了请求数据而安装了 this.$http,或者为了国际化而安装了 this.$translate。为了使 TypeScript 更好地支持这个行为,Vue 暴露了一个被设计为可以通过 TypeScript 模块扩展来扩展的 ComponentCustomProperties 接口:

import axios from 'axios'
declare module 'vue' {
  interface ComponentCustomProperties {
    $http: typeof axios
    $translate: (key: string) => string
  }
}
类型扩展的位置

我们可以将这些类型扩展放在一个 .ts 文件,或是一个影响整个项目的*.d.ts文件中。无论哪一种,都应确保在 tsconfig.json 中包括了此文件。对于库或插件作者,这个文件应该在 package.jsontypes 属性中被列出。
为了利用模块扩展的优势,你需要确保将扩展的模块放在 TypeScript 模块 中。 也就是说,该文件需要包含至少一个顶级的 importexport,即使它只是 export {}。如果扩展被放在模块之外,它将覆盖原始类型,而不是扩展!

// 不工作,将覆盖原始类型。
declare module 'vue' {
  interface ComponentCustomProperties {
    $translate: (key: string) => string
  }
}
// 正常工作。
export {}

declare module 'vue' {
  interface ComponentCustomProperties {
    $translate: (key: string) => string
  }
}
扩展自定义选项

某些插件,比如 vue-router,提供了一些自定义的组件选项,比如 beforeRouteEnter

import { defineComponent } from 'vue' 

export default defineComponent({
  beforeRouteEnter(to, from, next) {
    // ...
  }
})

如果没有确切的类型标注,这个钩子函数的参数会隐式地标注为 any 类型。我们可以为 ComponentCustomOptions 接口扩展自定义的选项来支持:

import { Route } from 'vue-router'

declare module 'vue' {
  interface ComponentCustomOptions {
    beforeRouteEnter?(to: Route, from: Route, next: () => void): void
  }
}

现在这个 beforeRouteEnter 选项会被准确地标注类型。注意这只是一个例子——像 vue-router 这种类型完备的库应该在它们自己的类型定义中自动执行这些扩展。
这种类型扩展和全局属性扩展受到相同的限制

我想大家比起云里雾里的官网说明,更简单的操作更直观

main.ts里面配置config

const app = createApp(App);
app.config.globalProperties.$http = client  //可以配置一个方法
app.config.globalProperties.$user = {		//也可以配置一个对象
	name:'粱友安',
	boyfriend:'宋三川'
}

template模板中使用

<span>姓名:{{$user.name + 'love' + $user.boyfriend}} </span>

setup中使用

const con = getCurrentInstance()
console.log(con.appContext.config.globalProperties.$user)
//或
const { proxy } = getCurrentInstance()
const http = proxy.$http;   // 这样就可以直接调用axios请求数据方法,如果你配置了的话

说明:其实本身使用并不复杂,但是通过ts进行封装了之后就会显得复杂

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐