在 Vue3 中挂载全局属性
定义全局属性
在 Vue2 中, Vue.prototype 通常用于添加所有组件都能访问的 property。
Vue.prototype.$http = axios
Vue.prototype.$name = 'xiaoming'
Vue.prototype.$print = function(d) {
console.log(d)
}
但是在 Vue3 中这种方式被废弃了,与之对应的是 config.globalProperties
。这些 property 将被复制到应用中,作为实例化组件的一部分。
const app = createApp({})
app.config.globalProperties.$http = axios
app.config.globalProperties.$name = 'xiaoming'
app.config.globalProperties.$print = function(d) {
console.log(d)
}
TypeScript 语法提示
如果项目中使用了 TypeScript,为了告诉 TypeScript 这些新 property,我们可以使用 模块扩充(module augmentation),
在上述示例中,我们可以添加以下类型声明(在项目中新建一个 d.ts 声明文件):
import axios from 'axios'
declare module '@vue/runtime-core' {
export interface ComponentCustomProperties {
$http: typeof axios
$name: string
$print: (data: any) => void
}
}
通过插件形式扩展(个人推荐做法)
可在项目中新建 plugins/VueEnhance.ts
插件文件,然后编写插件内容:
import axios from 'axios'
export default {
install: function (app: App<Element>, options: any): void {
const properties = app.config.globalProperties
properties.$http = axios
properties.$name = 'xiaoming'
properties.$print = function(d) {
console.log(d)
}
}
}
添加声明文件,提供 TypeScript 语法提示
import { createApp } from 'vue'
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$api: typeof import('axios')['default']
$name: string
$print: (data: any) => void
}
}
最后在 main.ts 中使用插件
import { createApp } from 'vue'
import App from './App.vue'
import VueEnhance from './plugins/VueEnhance'
createApp(App).use(VueEnhance).mount('#app')
使用 properties
前面我们已经定义好了自己的功能扩展,现在就开始在项目中使用吧。
在组合式API(Composition API)中使用
在组合式API中,TypeScript 能正确推导出 this 的类型,所以可以直接通过 this.$xxx
的形式来访问。
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
setup() {},
methods: {
test() {
console.log(this.$name)
}
}
})
</script>
在 script-setup 中使用
由于 getCurrentInstance 返回值的类型为 ComponentInternalInstance | null
,所以我们需要先强制转成 ComponentInternalInstance,这样在使用 proxy 的时候就能得到 TypeScript 的语法提示了。
<script lang="ts" setup>
import { ComponentInternalInstance, getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance() as ComponentInternalInstance
console.log(proxy?.$name)