vue3的全局变量挂载+ts的类型声明与使用

5,163 阅读2分钟

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"],

这样声明文件才能生效,如果用的是项目里已经存在并且引入了的声明文件,可以忽略上面两步