Vuex 商店和打字稿

Vuex store and typescript

我很好奇我选择的访问 vuex 存储的方式以及它是否会导致问题。

我有一个正在使用 VS-Code 的 vuex 项目,当我通过 this.$store 访问商店时,它显示了大多数项目的 any 类型。

例如

@Component
export default class Foo extends Vue {
  get bar(){
  return this.$store.state.bar
  }
  set bar(){
    this.$store.commit("setBar", value);
  }
}

但是,如果我导入商店,它将显示所有内容的正确输入。

例如

import store from "@/store";
@Component
export default class Foo extends Vue {
  get bar(){
  return store.state.bar
  }
  set bar(){
    store.commit("setBar", value);
  }
}

我已经测试并确认商店已按预期修改,任何更改的值都可以使用 this.$store 从其他页面获得。以这种方式访问​​商店似乎没有什么坏处,而且它还有一个额外的好处,那就是让我可能想使用的任何箭头功能都可以轻松访问商店。我错过了什么吗?

简短的回答是,是的,这行得通。导入的 store 实例与组件中的 this.$store 实例相同。

用法不同。组件的视图部分只能看到组件范围内的变量,但看不到全局变量。因此,在第一种情况下,您可以将组件视图部分中的栏称为 $store.state.bar。在第二种情况下,您必须像示例中那样为 bar 创建一个 getter。

第一种方法更传统,因此推荐使用。

现在,为什么类型推断在您的 IDE 中不起作用是另一个问题。可能有多种原因:

  • 最明显的是:VS Code 中的类型推断,或者更确切地说,我假设您使用的 Vetur 插件,是不完美的。您可能想尝试 WebStorm,我认为它在这方面要好一些。
  • 推断 bar 的类型有多难?您是否明确说明类型?您是否为商店状态定义了接口?

要充分利用 TypeScript,请尽可能明确地使用您的类型。例如,这个 Vuex store 很难猜测 bar 的类型:

export default new Vuex.Store({
  state: () => ({
    bar: null
  }),
  mutations: {
    setBar: function(state, bar) {
      state.bar = bar;
    }
  }
})

另一方面,这非常明确:

interface State {
  bar: Bar | null;
}

export default new Vuex.Store<State>({
  state: (): State => ({
    bar: null
  }),
  mutations: {
    setBar: function(state: State, bar: Bar) {
      state.bar = bar;
    }
  }
})

您可以在此处阅读有关正确输入 Vuex 存储的更多信息:

https://www.codeproject.com/Tips/5295301/Correctly-Typing-Vuex-with-TypeScript