getter 不会更新 Vuex 中的值

Dan*_*yar 1 javascript router vue.js vuex

我不明白 getter 在 Vuex 中是如何工作的。问题是当在 state 中注销令牌并且 localStorage 变空时,但在 getters 中则不然。在created我称之为:

created: async function () {
    if (this.$store.getters.shortToken) {
      this.isConfirm = true
    }
    console.log(
      'signining', localStorage.getItem('token'), // ''
      'state', this.$store.state.user.token, // ''
      'getter', this.$store.getters.token // 'old-token'
    )
    if (this.$store.getters.token) {
      await this.$router.push({ path: '/' })
    }
  }
Run Code Online (Sandbox Code Playgroud)

并且getters有:

token: state => {
    return localStorage.getItem('token') || state.user.token
  }
Run Code Online (Sandbox Code Playgroud)

mutation

SET_TOKEN: (state, payload) => {
      localStorage.setItem('token', payload.token)
      Object.assign(state, payload)
    }
Run Code Online (Sandbox Code Playgroud)

但是,创建的控制台登录给了我空的 localStorage 令牌(这是正常的)和空的 state.token (这也是正常的)。但是, getters.token 给了我令牌(这不正常),因为我给了 SET_TOKEN 空令牌。为什么会发生这种情况?
附言。如果我在 getters 令牌中添加console.log(state.user.token, localStorage.getItem('token'))上面的内容,那么 hook中是空的......为什么?在这种情况下也有一些使用代码,这是注销方法:returngetters.tokencreated

methods: {
    async logout () {
      if (await this.$store.dispatch('logOut')) {
        console.log('logged out')
        await this.$router.push({ path: '/signin' })
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

操作注销

async logOut (context) {
    console.log('logggog')
    context.commit('SET_TOKEN', {
      token: ''
    })
    context.commit('SET_USER', {
      user: null
    })
    return true
  }
Run Code Online (Sandbox Code Playgroud)

Cat*_*oha 5

Getter 旨在derived state基于 进行计算store state

localStorage.getItem()您面临这个问题是因为您从 your返回 的值Getter,这不是 的值store state,因此它不是reactiveobservable

在您的示例中,当您调用 时,Vuex 不会重新计算 Getter 的值localStorage.setItem()。仅当更改
时才会重新计算 Getter 的值。state.user.token

因此,如果您想让 Getter 正常工作,请仅返回 的值state.user.token
您还可以created在您的文件中添加一个钩子,App.vue检查 localStorage 中是否有令牌并调用突变SET_TOKEN(如果您试图通过调用localStorage.getItemGetter 来实现这一点):

App.vue

<script>
    created() {
        const token = localStorage.getItem('token');
        if (token != null) {
            this.$store.mutations.SET_TOKEN({ token });
        }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

尽管如此,使用时请注意变更检测警告Object.assign,因为 Vuex突变遵循 Vue 的反应性规则

在你的突变中你可能应该这样做:

SET_TOKEN: (state, payload) => {
    localStorage.setItem('token', payload.token);
    state.token = payload.token;
}
Run Code Online (Sandbox Code Playgroud)

或者如果payload实际上state.user你可以这样做:

SET_TOKEN: (state, payload) => {
    localStorage.setItem('token', payload.token);
    state.user = {
       ...payload
    }
}
Run Code Online (Sandbox Code Playgroud)