首页 > 解决方案 > Vue.js:在用户登录或未登录时根据 Vuex Store 状态在导航栏上显示/隐藏按钮

问题描述

我正在创建一个导航栏,根据用户是否登录来显示或隐藏按钮。为此,我将状态保存在 Vuex 和 localStorage 上。

我正在尝试构建一个动态菜单,使用rightMenu包含按钮信息的对象列表(即)(即路线、标题和一个标志,指示如果用户登录,按钮是否可以显示)。

始终是用户登录系统,this.$store.state.auth.isUserLoggedIn更改为true,但模板没有更改,按钮在用户未登录时保持相同的初始状态。例如:更新sign out时按钮不显示this.$store.state.auth.isUserLoggedIn。但是当我单击“ctrl+F5”并重新加载页面时,按钮会正确显示。例如,在这种情况下,sign out当我手动重新加载页面时,按钮会正确显示。

我正在考虑在用户登录或注销时强制页面重新加载,但是我认为这不是一个好选择。

有人可以帮我吗?

我在下面给出我正在使用的代码。

先感谢您。

Menu.vue > 模板

<div>
    <v-toolbar color='grey darken-3' dark>
        <v-toolbar-title>Site</v-toolbar-title>

        ...

        <v-toolbar-items class='hidden-sm-and-down'>
            <v-btn v-for='item in rightMenu' :key='item.title'
                   :to='item.to' v-if='item.showButton' flat>
                   {{ item.title }}
            </v-btn>
        </v-toolbar-items>

    </v-toolbar>

    <router-view/>
</div>

Menu.vue > 脚本

export default {
  data () {
    return {
      rightMenu: [
        { to: '/sign_in', title: 'sign in'
          showButton: !this.$store.state.auth.isUserLoggedIn },
        { to: '/sign_up', title: 'sign up'
          showButton: !this.$store.state.auth.isUserLoggedIn },
        { to: '/sign_out', title: 'sign out'
          showButton: this.$store.state.auth.isUserLoggedIn }
      ]
    }
  },
  ...
}

store.js

const store = new Vuex.Store({
  state: {
    auth: {
      token: '',
      isUserLoggedIn: false
    }
  },
  mutations: {
    setAuthToken (state, token) {  // I use it on the Login
      state.auth.token = token
      state.auth.isUserLoggedIn = !!token
      localStorage.setItem('store', JSON.stringify(state))
    },
    cleanAuth (state) {  // I use it on the Logout
      state.auth = {
        token: '',
        isUserLoggedIn: false
      }
      localStorage.setItem('store', JSON.stringify(state))
    }
  }
  ...
})

编辑1:

当我this.$store.state.auth.isUserLoggedIn在我的代码上明确使用时,它运行良好。因此,按钮正确出现和消失。我在下面举一个例子:

Menu.vue > 模板

<v-toolbar-items class='hidden-sm-and-down'>
    <v-btn v-if='this.$store.state.auth.isUserLoggedIn' flat> 
      Test {{ this.$store.state.auth.isUserLoggedIn }}
    </v-btn>
</v-toolbar-items>

因此,我认为问题在于showButtonwith的绑定this.$store.state.auth.isUserLoggedIn

标签: javascriptvue.jslocal-storagevuexvue-cli-3

解决方案


使用computed属性来制作它reactive

<template>
...
<v-btn v-for='item in rightMenu' :key='item.title'
  :to='item.to' v-if='isUserLoggedIn(item.title)' flat>
  {{ item.title }}
</v-btn>
...
</template>

<script>
...
computed: {
  isUserLoggedIn() {
    return (title) => {  // you'll not have any caching benefits
      if (title === 'sign out') {
        return this.$store.state.auth.isUserLoggedIn;
      }
      return !this.$store.state.auth.isUserLoggedIn;
    }
  }
}
...
</script>


推荐阅读