TypeScript 支持

Vuex 提供了其类型,因此您可以使用 TypeScript 来编写存储定义。您不需要任何特殊的 TypeScript 配置来使用 Vuex。请遵循 Vue 的基本 TypeScript 设置 来配置您的项目。

但是,如果您使用 TypeScript 编写 Vue 组件,则需要遵循几个步骤才能为存储提供正确的类型。

在 Vue 组件中为 $store 属性添加类型

Vuex 不会为 this.$store 属性提供开箱即用的类型。在使用 TypeScript 时,您必须声明自己的模块增强。

为此,请通过在项目文件夹中添加一个声明文件来为 Vue 的 ComponentCustomProperties 声明自定义类型

// vuex.d.ts
import { Store } from 'vuex'

declare module '@vue/runtime-core' {
  // declare your own store states
  interface State {
    count: number
  }

  // provide typings for `this.$store`
  interface ComponentCustomProperties {
    $store: Store<State>
  }
}

useStore 组合函数添加类型

当您使用组合式 API 编写 Vue 组件时,您很可能希望 useStore 返回类型化的存储。为了使 useStore 正确返回类型化的存储,您必须

  1. 定义类型化的 InjectionKey
  2. 在将存储安装到 Vue 应用程序时提供类型化的 InjectionKey
  3. 将类型化的 InjectionKey 传递给 useStore 方法。

让我们一步一步地解决这个问题。首先,使用 Vue 的 InjectionKey 接口以及您自己的存储类型定义来定义键

// store.ts
import { InjectionKey } from 'vue'
import { createStore, Store } from 'vuex'

// define your typings for the store state
export interface State {
  count: number
}

// define injection key
export const key: InjectionKey<Store<State>> = Symbol()

export const store = createStore<State>({
  state: {
    count: 0
  }
})

接下来,在将存储安装到 Vue 应用程序时传递定义的注入键

// main.ts
import { createApp } from 'vue'
import { store, key } from './store'

const app = createApp({ ... })

// pass the injection key
app.use(store, key)

app.mount('#app')

最后,您可以将键传递给 useStore 方法以检索类型化的存储。

// in a vue component
import { useStore } from 'vuex'
import { key } from './store'

export default {
  setup () {
    const store = useStore(key)

    store.state.count // typed as number
  }
}

在幕后,Vuex 使用 Vue 的 Provide/Inject 功能将存储安装到 Vue 应用程序,这就是为什么注入键是一个重要因素。

简化 useStore 的使用

到处导入 InjectionKey 并将其传递给 useStore 会很快变成一项重复的任务。为了简化问题,您可以定义自己的可组合函数来检索类型化的存储

// store.ts
import { InjectionKey } from 'vue'
import { createStore, useStore as baseUseStore, Store } from 'vuex'

export interface State {
  count: number
}

export const key: InjectionKey<Store<State>> = Symbol()

export const store = createStore<State>({
  state: {
    count: 0
  }
})

// define your own `useStore` composition function
export function useStore () {
  return baseUseStore(key)
}

现在,通过导入您自己的可组合函数,您可以检索类型化的存储,**无需**提供注入键及其类型

// in a vue component
import { useStore } from './store'

export default {
  setup () {
    const store = useStore()

    store.state.count // typed as number
  }
}