Vue 3 使用 Typescript 注入

Posted

技术标签:

【中文标题】Vue 3 使用 Typescript 注入【英文标题】:Vue 3 Inject with Typescript 【发布时间】:2021-04-19 08:26:21 【问题描述】:

我使用了新的 Vue 3 组合 API,并为响应式数据编写了一个“存储”。

const state = reactive<State>(
  accessToken: undefined,
  user: undefined,
);

export default 
  state: readonly(state),

在创建应用时,我将商店提供给所有组件:

const app = createApp(App)
  .provide("store", store)
  .use(IonicVue)
  .use(router);

最后在一个组件/视图中,我注入 store 以使用它。

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 属性 email() 中使用 this.store 的方式@

然后说

类型“ComponentPublicInstance>'

我的意思是当我删除&lt;script/&gt; 标记中的lang="ts" 时一切正常,但没有显示错误。 关于如何解决这个问题或它的特别含义有什么建议吗?

提前致谢!

【问题讨论】:

【参考方案1】:

对于那些使用 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 读取/写入 Store.myProperty

【讨论】:

手表怎么用?在设置中【参考方案2】:

我建议将 store 用作全局属性,而不在任何子组件中指定 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 使用 Typescript 注入的主要内容,如果未能解决你的问题,请参考以下文章

在 Vue 3 Typescript 中将道具传递给数据对象

Vue JS typescript 组件找不到注入实例属性

vue-type-check: Vue 模板中的 Typescript 类型检查

Jest、Vue3 和 Typescript:如何通过符号模拟注入?

Vue 3 + Vue Router 4:TypeError:无法读取未定义的属性(读取“推送”)

Vue.js 2.5新特性介绍(推荐)