【问题标题】:How to set the initial state in Vuex dynamically (using "if") when initializing?初始化时如何在Vuex中动态设置初始状态(使用“if”)?
【发布时间】:2019-10-30 18:23:28
【问题描述】:

Vue/Vuex 初学者在这里。有没有办法在 Vuex 中动态设置初始状态?我有一个名为 is_here 的布尔状态(true 如果存在成员),我想在设置之前使用条件语句动态检查其值。

如果我尝试编译如下代码,则会返回此错误:TS2564: Property 'is_here' has no initializer and is not definitely assigned in the constructor.

import { Action, Module, Mutation, VuexModule, getModule } from 'vuex-module-decorators';

export interface IMemberState {
  is_here: boolean;
}

@Module({dynamic: true, store, name: 'member', namespaced: true})
class Member extends VuexModule implements IMemberState {
  public is_here: boolean // The app expects me to set true or false here
}

如果我将初始化程序的默认值设置为truefalse,则应用程序编译正确。但是,如果我更改状态(假设从 truefalse)并刷新页面,状态将恢复为 true(基于此布尔值呈现不同的按钮,因此我可以看到它已恢复为true)。

public is_here: boolean = true

我想做的是在设置is_here 状态之前进行 API 调用并检查某些事情。我写了一个@Action 来进行必要的检查。

@Action({})
public async setHereStatus() {
  await axios.get('api/member_status').then((response)=>
  if(response.here_status) {
  // This action returns true or false
  )
}

我尝试将这个 @Action 放入而不是硬编码 is_here 的值会起作用,但我收到了这个错误:TS2322: Type '() => Promise<boolean>' is not assignable to type 'boolean'.

public is_here: boolean = this.setHereStatus()

如何在这种情况下动态分配此状态?我应该使用createdmounted 之类的东西吗?


[更新] 正如@ittus 评论的那样,我应该使用@Mutation 来设置is_here 状态。我一直在做这样的实验。

@Module({dynamic: true, store, name: 'member', namespaced: true})
class Member extends VuexModule implements IMemberState {
  public is_here: boolean = false

  @Mutation
  public SET_HERE_STATUS(status: boolean): void {
    this.is_here = status
  }

  @Action({})
  public async setHereStatus() {
    await axios.get('api/member_status').then((response)=>
    if(response.here_status) {
      this.SET_HERE_STATUS(true)
    }else {
      this.SET_HERE_STATUS(false)
  }
}
// In the Vue component where I use this state
  created () {
    memberModule.setHereStatus()
  }

但是,同样的问题仍然存在;如果我刷新页面,或关闭窗口并再次访问相同的 URL,状态将被重置。我不知道我的created 钩子是否正常工作。

【问题讨论】:

  • if I refresh the page, or close the window and access the same URL again, the state is reset. -> Vuex 不会自动保持状态。如果您想在页面重新加载时保持状态,则需要定期存储状态,例如在本地存储中。有插件。
  • 我在question 中读到了这一点,所以我正在研究它。就我而言,当我正确配置 created 挂钩时,即使我刷新或重新打开页面,状态也会持续存在。不知道什么样的情况需要使用localStorage...有明显的区别吗?

标签: typescript vue.js state vuex


【解决方案1】:

你应该调用 mutation 来更新 vuex 状态。

或者您可以将突变和动作与 MutationAction 结合起来

@Module({dynamic: true, store, name: 'member', namespaced: true})
class Member extends VuexModule implements IMemberState {
  public is_here: false
  public is_here_loaded: false

  @MutationAction({mutate: ['is_here', 'is_here_loaded']})
  public async setHereStatus() {
    const response = await axios.get('api/member_status')
    return {
      is_here: response.here_status,
      is_here_loaded: true
    }
  }
}

您可以将默认值设置为false。如果您需要等待变量is_here 被设置,您可以使用附加标志来检查。在上面的代码中,我使用is_here_loaded作为标志变量。

setHereStatus应该在组件created时调用

【讨论】:

  • 谢谢。是否可以举例说明如何使用普通的@Mutation@Action 而不是@MutationAction?我更新了我的问题,因为我意识到我需要使用 @Mutation,但我仍然遇到同样的问题。
  • 创建的钩子应该在 Vue 组件中,而不是在 vuex 模块中。
  • 刚刚意识到这一点,并修复了代码示例。它现在似乎正在工作。谢谢!
猜你喜欢
  • 2018-07-04
  • 2017-06-09
  • 2018-06-30
  • 1970-01-01
  • 1970-01-01
  • 2019-05-08
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多