使用 TypeScript 将全局属性添加到 Vue 3
Add global properties to Vue 3 using TypeScript
我想像建议的那样将全局 属性 添加到 Vue 3 应用程序 here
原型方法不适用于 TypeScript。
我找到了一个示例,我将其转换为此代码 config.d.ts
import Vue from 'vue'
import base from '@/config/config.json'
import dev from '@/config/config.dev.json'
import prod from '@/config/config.prod.json'
let config
if (process.env.NODE_ENV === 'production') {
config = Object.freeze(Object.assign(base, prod))
} else {
config = Object.freeze(Object.assign(base, dev))
}
declare module 'vue/types/vue' {
interface Vue {
$config: config
}
}
我想加载一些具有 dev 或 prod 范围的本地配置文件。范围内的文件将不会签入 GIT 存储库。
main.ts 现在看起来像这样...
import Vue from 'vue'
import {createApp} from 'vue'
import App from './App.vue'
import Config from '@/plugins/config.d.ts'
Vue.use(Config)
createApp(App).mount('#app')
问题:
ERROR in src/main.ts:6:5
TS2339: Property 'use' does not exist on type 'typeof import("d:/Martin/Entwicklung/2020/STA-Electron/node_modules/vue/dist/vue")'.
4 | import Config from '@/plugins/config.d.ts'
5 |
> 6 | Vue.use(Config)
| ^^^
7 | createApp(App).mount('#app')
8 |
我理想中想要实现的是全局的config
或者$config
属性可以在Vue 3
的setup方法中使用
export default defineComponent({
name: 'App',
components: {},
setup(props, context) {
const elem = ref(context.$config.prop1)
const doSth = () => {
console.log('Config', context.$config)
}
return {doSth, elem}
},
})
我该如何解决这个问题?
更新
在 danielv 的回答后,新插件看起来像这样
import {App} from 'vue'
export interface ConfigOptions {
base: any
dev: any
prod: any
}
export default {
install: (app: App, options: ConfigOptions) => {
app.config.globalProperties.$config =
process.env.NODE_ENV === 'production'
? Object.freeze(Object.assign({}, options.base, options.prod))
: Object.freeze(Object.assign({}, options.base, options.dev))
},
}
main.ts也改成了这个
import {createApp} from 'vue'
import App from '@/App.vue'
import ConfigPlugin from '@/plugins/config'
import base from '@/config/config.json'
import dev from '@/config/config.dev.json'
import prod from '@/config/config.prod.json'
createApp(App).use(ConfigPlugin, {base, dev, prod}).mount('#app')
这个简单的插件可以在模板中使用
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<p>{{ $config.prop1 }}</p>
</template>
IntelliJ 抱怨未知变量 prop1,但它有效。
我搜索了很多,但找不到将我的 $config 插入组合 api.
使用的设置方法的方法
在 Vue 3 中,您在应用实例上调用 use
方法,它不是 Vue 变量上的方法。
const app = createApp(App)
app.mount('#app')
app.use(config)
此外,您需要编写插件以符合 Vue 3 的预期(具有 install
方法的对象)。
查看 Vue 3 guide 关于编写和使用插件的内容,它描述了一个与您非常相似的用例。
顺便说一下,*.d.ts
文件旨在用作纯声明文件来声明类型,通常作为对其他非类型化模块的补充(例如键入现有的 js 代码)。在编写 Typescript 代码时,您通常不需要自己编写 *.d.ts
文件(声明可以由 tsc 编译器自动生成)。
您可以在应用程序中扩充 @vue/runtime-core
TypeScript 模块:
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$config: Record<string, unknown>;
}
}
export {} // Important! See note.
这是一个文档:ComponentCustomProperties
重要说明: TS 模块扩充正常工作 仅当 放在 module.[=22= 中时]
In TypeScript, just as in ECMAScript 2015, any file containing a
top-level import
or export
is considered a module. Conversely, a
file without any top-level import
or export
declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).
因此该文件必须包含至少一个 top-level import
或 export
语句,即使是空语句(如上例所示)- Type Augmentation Placement
我想像建议的那样将全局 属性 添加到 Vue 3 应用程序 here
原型方法不适用于 TypeScript。
我找到了一个示例,我将其转换为此代码 config.d.ts
import Vue from 'vue'
import base from '@/config/config.json'
import dev from '@/config/config.dev.json'
import prod from '@/config/config.prod.json'
let config
if (process.env.NODE_ENV === 'production') {
config = Object.freeze(Object.assign(base, prod))
} else {
config = Object.freeze(Object.assign(base, dev))
}
declare module 'vue/types/vue' {
interface Vue {
$config: config
}
}
我想加载一些具有 dev 或 prod 范围的本地配置文件。范围内的文件将不会签入 GIT 存储库。
main.ts 现在看起来像这样...
import Vue from 'vue'
import {createApp} from 'vue'
import App from './App.vue'
import Config from '@/plugins/config.d.ts'
Vue.use(Config)
createApp(App).mount('#app')
问题:
ERROR in src/main.ts:6:5
TS2339: Property 'use' does not exist on type 'typeof import("d:/Martin/Entwicklung/2020/STA-Electron/node_modules/vue/dist/vue")'.
4 | import Config from '@/plugins/config.d.ts'
5 |
> 6 | Vue.use(Config)
| ^^^
7 | createApp(App).mount('#app')
8 |
我理想中想要实现的是全局的config
或者$config
属性可以在Vue 3
export default defineComponent({
name: 'App',
components: {},
setup(props, context) {
const elem = ref(context.$config.prop1)
const doSth = () => {
console.log('Config', context.$config)
}
return {doSth, elem}
},
})
我该如何解决这个问题?
更新
在 danielv 的回答后,新插件看起来像这样
import {App} from 'vue'
export interface ConfigOptions {
base: any
dev: any
prod: any
}
export default {
install: (app: App, options: ConfigOptions) => {
app.config.globalProperties.$config =
process.env.NODE_ENV === 'production'
? Object.freeze(Object.assign({}, options.base, options.prod))
: Object.freeze(Object.assign({}, options.base, options.dev))
},
}
main.ts也改成了这个
import {createApp} from 'vue'
import App from '@/App.vue'
import ConfigPlugin from '@/plugins/config'
import base from '@/config/config.json'
import dev from '@/config/config.dev.json'
import prod from '@/config/config.prod.json'
createApp(App).use(ConfigPlugin, {base, dev, prod}).mount('#app')
这个简单的插件可以在模板中使用
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<p>{{ $config.prop1 }}</p>
</template>
IntelliJ 抱怨未知变量 prop1,但它有效。
我搜索了很多,但找不到将我的 $config 插入组合 api.
使用的设置方法的方法在 Vue 3 中,您在应用实例上调用 use
方法,它不是 Vue 变量上的方法。
const app = createApp(App)
app.mount('#app')
app.use(config)
此外,您需要编写插件以符合 Vue 3 的预期(具有 install
方法的对象)。
查看 Vue 3 guide 关于编写和使用插件的内容,它描述了一个与您非常相似的用例。
顺便说一下,*.d.ts
文件旨在用作纯声明文件来声明类型,通常作为对其他非类型化模块的补充(例如键入现有的 js 代码)。在编写 Typescript 代码时,您通常不需要自己编写 *.d.ts
文件(声明可以由 tsc 编译器自动生成)。
您可以在应用程序中扩充 @vue/runtime-core
TypeScript 模块:
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$config: Record<string, unknown>;
}
}
export {} // Important! See note.
这是一个文档:ComponentCustomProperties
重要说明: TS 模块扩充正常工作 仅当 放在 module.[=22= 中时]
In TypeScript, just as in ECMAScript 2015, any file containing a top-level
import
orexport
is considered a module. Conversely, a file without any top-levelimport
orexport
declarations is treated as a script whose contents are available in the global scope (and therefore to modules as well).
因此该文件必须包含至少一个 top-level import
或 export
语句,即使是空语句(如上例所示)- Type Augmentation Placement