VUEJS 3 组合计算和 vuex 没有反应

Posted

技术标签:

【中文标题】VUEJS 3 组合计算和 vuex 没有反应【英文标题】:VUEJS 3 composition computed and vuex not reactive 【发布时间】:2021-09-20 08:58:49 【问题描述】:

我正在尝试使用 vuejs3 和组合 api 构建网站,并且我正在使用 VUEX 4 进行状态管理。

目前我正在设置登录功能,它运行良好。 唯一不起作用的是计算属性的反应性。在导航栏中,我有一个计算属性,用于将登录和注册选项更改为仪表板和注销。

这是我的商店模块,名为“auth”

export default 
namespaced: true,
state: 
    token: false,
    user: false,
    is_Authenticated: false
,
getters: 
    is_Authenticated(state) 
        return state.token && state.user;
    ,
    get_User(state) 
        return state.user;
    
,

在我的导航中有这个。

<script>
import  ref, computed, defineComponent  from 'vue';
import  useStore  from 'vuex';
import  useRouter, useRoute  from 'vue-router'
import Menubar from 'primevue/menubar';

export default defineComponent(
  name: "Navbar",
  components: 
    Menubar
  ,
  setup()
    const store = useStore();
    const router = useRouter();

    const is_Authenticated = computed(() => store.getters['auth/is_Authenticated']);

当我登录时,“state.user”和“state.token”的值会被相应的数据填充,据我所知,getter 应该返回 true。 然后更新计算的属性。那么导航应该会改变

我在导航中使用以下内容


  label: 'Account',
  icon: 'pi pi-user',
  items:[
    
      label: 'Login',
      to: '/login',
      visible: !is_Authenticated
    ,
    
      label: 'Register',
      to: '/register',
      visible: !is_Authenticated
    ,
    
      label: 'Dashboard',
      to: '/dashboard',
      visible: is_Authenticated,
    ,
    
      label: 'Logout',
      visible: is_Authenticated,
      command: () => 
        store.dispatch('auth/logout')
        .then(() => 
          router.replace(
            name: 'Home'
          );
        )
      
    ,

这是导航栏的值。小记:我用的是PrimeVue组件库

const items = ref([
  
    label: 'Home',
    icon: 'pi pi-home',
    to: '/'
  ,
  
    label: 'Account',
    icon: 'pi pi-user',
    items:[
      
        label: 'Login',
        to: '/login',
        visible: !is_Authenticated
      ,
      
        label: 'Register',
        to: '/register',
        visible: !is_Authenticated
      ,
      
        label: 'Dashboard',
        to: '/dashboard',
        visible: is_Authenticated,
      ,
      
        label: 'Logout',
        visible: is_Authenticated,
        command: () => 
          store.dispatch('auth/logout')
          .then(() => 
            router.replace(
              name: 'Home'
            );
          )

        
      ,
    ]
  
]);

现在您会在登录时看到计算出的“is_Authenticated”为真,一切都会很好。 但是计算的根本不更新。没有反应性。 getter "is_Authenticated" 也返回 state.user 而不是 true 或 false。

我已经尝试使用一个名为“is_Authenticated”的状态变量并让 getter 返回它。 在 VUE 开发工具中,我将 is_Authenticated 的值从 false 更改为 true,并看到 getter 正在更新,但页面没有。 计算的 getter 根本没有响应。

我很可能在边学习边做错事。 但希望有人能解决这个问题。 谢谢

【问题讨论】:

is_Authenticated 是一个参考。将其用作visible: !is_Authenticated 之类的值是错误的。要么将 ref 传递到消耗 visible 的地方,要么将整个 items 计算为一个。 【参考方案1】:

因此,按照 Estus Flask 的建议,我将菜单项数组移到了商店。 创建一个名为“导航”的模块 这是完整的商店。

import store from '../index';
import axios from 'axios';


export default 
    namespaced: true,
    state: 
        is_Authenticated: false,
        menu: [
            
                label: 'Home',
                icon: 'pi pi-home',
                to: '/'
            ,
            
                label: 'Account',
                icon: 'pi pi-user',
                items:[
                    
                        label: 'Login',
                        to: '/login',
                        visible: () => !store.getters['navigation/get_Authentication'],
                    ,
                    
                        label: 'Register',
                        to: '/register',
                        visible: () => !store.getters['navigation/get_Authentication'],
                    ,
                    
                        label: 'Dashboard',
                        to: '/dashboard',
                        visible: () => store.getters['navigation/get_Authentication'],
                    ,
                    
                        label: 'Logout',
                        visible: () => store.getters['navigation/get_Authentication'],
                        command: () => store.dispatch('navigation/logout'),
                    ,
                ]
            
        ],
    ,
    getters: 
        get_Menu_Items(state) 
            return state.menu;
        ,
        get_Authentication()
            return store.getters['auth/is_Authenticated']
        
    ,
    mutations: 
    ,
    actions: 
        async logout(commit, dispatch, needsAuthentication) 
            store.dispatch('auth/logout')
                .catch((e)=>
                    console.log(e);
               );
        
    ,

我知道如果这样做可能是更好的方法,但效果非常好。 在“auth”模块中还发现,返回 true 的用户和令牌设置的检查应该有 2 个感叹号。

getter 代码现在是:

is_Authenticated(state) 
    return !!(state.user && state.token);
,

现在从我调用的导航栏组件

const items = computed( () => store.getters['navigation/get_Menu_Items']);

再次感谢您的建议。 我花了一段时间才得到这个工作。 希望现在可以了^_^

【讨论】:

以上是关于VUEJS 3 组合计算和 vuex 没有反应的主要内容,如果未能解决你的问题,请参考以下文章

无法通过getter vuex vuejs访问状态

VueJS + Vue.Draggable + Vuex Store + 计算变量

VueJS - Vuex 状态更新时组件不更新

VueJs 3 - Vuex:未捕获的类型错误:存储不是函数

Vuex + VueJS:未定义将计算属性传递给孩子

循环遍历 Vuejs 中的 mapstate 计算属性