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.json
的 types
属性中被列出。
为了利用模块扩展的优势,你需要确保将扩展的模块放在 TypeScript
模块 中。 也就是说,该文件需要包含至少一个顶级的 import
或 export
,即使它只是 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
进行封装了之后就会显得复杂