vue3的全局变量挂载+ts的类型声明与使用
-
vue3全局变量挂载
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
// vue3全局变量挂载
app.config.globalProperties.$http = http
const demo = 'demo'
app.config.globalProperties.$demo = demo
app.mount('#app')
vue3是用globalProperties这个属性来挂载全局变量的。
挂载完后在vue文件中使用,template可直接调用
<template>
<div>
{{ $demo }}
</div>
</template>
script中传统方法下使用跟以前一样
<script lang="ts">
export default {
mounted() {
console.log(this.$demo)
}
}
</script>
script中setup语法糖下使用,由于setup没有this,所以需要导入获取当前实例的方法,解构到proxy来使用
<script lang="ts" setup>
import { reactive, ref, getCurrentInstance } from 'vue'
// 引入vue组件内部实例类型用于引入全局变量的类型断言
import type { ComponentInternalInstance } from 'vue'
const currentInstance = C()
// 使用getCurrentInstanceAPI获取全局对象方法一
// 从globalProperties中可以获取到所有的全局变量
// const globalProperties = currentInstance?.appContext.config.globalProperties
// console.log(globalProperties);
// 使用getCurrentInstanceAPI获取全局对象方法二
// 可以把proxy变量理解为原来的this
// const proxy = currentInstance?.proxy
// 这里 getCurrentInstance() 的ts类型检测是ComponentInternalInstance | null,所以需要类型断言,才能解构出 proxy
const { proxy } = getCurrentInstance() as ComponentInternalInstance
console.log(proxy.$demo)
// 全局挂载了elementui的ELMessage组件,这里才有这个$message
proxy.$message.success('getCurrentInstance')
</script>
上面变量demo引用爆红,是因为ts类型检测到proxy下没有demo和$message变量,要解决这个问题需要在写一个声明文件来扩展vue的接口
如果项目中没有现成的声明文件可以使用,可以自己创建一个,例如在src下自定义名字创建一个叫 typing.d.ts 的声明文件。
typing.d.ts
// 注意,扩展vue的接口需要先import vue进来, 不导入原来的环境进来,直接扩展的话,就不是扩展了,变成覆盖
import Vue from 'vue'
// 引入了element-plus的Message的ts类型声明
import type { Message } from 'element-plus'
declare module '@vue/runtime-core' {
// 扩展全局变量的接口内容,需要扩展ComponentCustomProperties这个接口,不要乱改成别的
interface ComponentCustomProperties {
$demo: string,
$message: Message
}
}
-
tsconfig.json配置
自己添加的声明文件,需要在tsconfig.json或jsconfig.json里配置一下,在include里把文件完整路径加上
"extends": "@vue/tsconfig/tsconfig.web.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/typing.d.ts"],
这样声明文件才能生效,如果用的是项目里已经存在并且引入了的声明文件,可以忽略上面两步