Vue 3 注入打字稿
Vue 3 Inject with Typescript
我使用新的 Vue 3 Composition API 并为响应式数据编写了一个“存储”。
const state = reactive<State>({
accessToken: undefined,
user: undefined,
});
export default {
state: readonly(state),
}
在创建 App 时,我将商店提供给所有组件:
const app = createApp(App)
.provide("store", store)
.use(IonicVue)
.use(router);
最后在组件/视图中,我注入商店以使用它。
export default defineComponent({
name: "Home",
inject: ["store"],
components: {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonButton,
},
computed: {
email() {
return this.store.state.user.email;
},
},
});
</script>
不幸的是 Typescript 不喜欢 我在 computed 属性 [=] 中使用 this.store
的方式14=]
并说
Property 'store' does not exist on type 'ComponentPublicInstance<{},
{}, {}, { email(): any; }, {}, EmitsOptions, {}, {}, false,
ComponentOptionsBase<{}, {}, {}, { email(): any; }, {},
ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string,
{}>>'
我的意思是当我删除 <script/>
标签中的 lang="ts"
时一切正常,但没有显示错误。
关于如何解决这个问题或它的具体含义有什么建议吗?
提前致谢!
我建议将商店用作全局 属性 而无需在任何子组件中指定 inject
因为 provide/inject 可能有一些 reactivity 警告:
const app = createApp(App)
.use(IonicVue)
.use(router);
app.config.globalProperties.store= store;
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
store:any // replace it with the right type
}
}
那就直接用吧:
export default defineComponent({
name: "Home",
components: {
...
},
computed: {
email() {
return this.store.state.user.email;
},
},
});
</script>
对于那些使用 Vue 3 + TS 处理相同问题的人,我找到了一个解决方案,无需更改 app.config
或声明新的 module
:
- App.ts 设置
import { createApp, reactive } from 'vue'
import App from './App.vue'
const Store = reactive({
myProperty: 'my value'
})
createApp(App)
.provide('Store', Store)
.mount('#app')
- 访问注入反应对象的组件:
<template>
<div>{{ Store.myProperty }}</div>
</template>
<script lang="ts">
import { IStore } from '@/types'
import { defineComponent, inject } from 'vue'
export default defineComponent({
name: 'MyComponentName',
setup() {
return {
Store: inject('Store') as IStore,
}
},
created() {
console.log(this.Store) // will show the `Store` in the console
}
})
</script>
- Store (
@/types.ts
) 的类型定义:
export interface IStore {
myProperty: string
}
按照这 3 个步骤,我可以使用 TypeScript read/write 到 Store.myProperty
而没有问题
我使用新的 Vue 3 Composition API 并为响应式数据编写了一个“存储”。
const state = reactive<State>({
accessToken: undefined,
user: undefined,
});
export default {
state: readonly(state),
}
在创建 App 时,我将商店提供给所有组件:
const app = createApp(App)
.provide("store", store)
.use(IonicVue)
.use(router);
最后在组件/视图中,我注入商店以使用它。
export default defineComponent({
name: "Home",
inject: ["store"],
components: {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonButton,
},
computed: {
email() {
return this.store.state.user.email;
},
},
});
</script>
不幸的是 Typescript 不喜欢 我在 computed 属性 [=] 中使用 this.store
的方式14=]
并说
Property 'store' does not exist on type 'ComponentPublicInstance<{}, {}, {}, { email(): any; }, {}, EmitsOptions, {}, {}, false, ComponentOptionsBase<{}, {}, {}, { email(): any; }, {}, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, string, {}>>'
我的意思是当我删除 <script/>
标签中的 lang="ts"
时一切正常,但没有显示错误。
关于如何解决这个问题或它的具体含义有什么建议吗?
提前致谢!
我建议将商店用作全局 属性 而无需在任何子组件中指定 inject
因为 provide/inject 可能有一些 reactivity 警告:
const app = createApp(App)
.use(IonicVue)
.use(router);
app.config.globalProperties.store= store;
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
store:any // replace it with the right type
}
}
那就直接用吧:
export default defineComponent({
name: "Home",
components: {
...
},
computed: {
email() {
return this.store.state.user.email;
},
},
});
</script>
对于那些使用 Vue 3 + TS 处理相同问题的人,我找到了一个解决方案,无需更改 app.config
或声明新的 module
:
- App.ts 设置
import { createApp, reactive } from 'vue'
import App from './App.vue'
const Store = reactive({
myProperty: 'my value'
})
createApp(App)
.provide('Store', Store)
.mount('#app')
- 访问注入反应对象的组件:
<template>
<div>{{ Store.myProperty }}</div>
</template>
<script lang="ts">
import { IStore } from '@/types'
import { defineComponent, inject } from 'vue'
export default defineComponent({
name: 'MyComponentName',
setup() {
return {
Store: inject('Store') as IStore,
}
},
created() {
console.log(this.Store) // will show the `Store` in the console
}
})
</script>
- Store (
@/types.ts
) 的类型定义:
export interface IStore {
myProperty: string
}
按照这 3 个步骤,我可以使用 TypeScript read/write 到 Store.myProperty
而没有问题