Vue 使用 vuex 从另一个组件控制和更新状态

Posted

技术标签:

【中文标题】Vue 使用 vuex 从另一个组件控制和更新状态【英文标题】:Vue control and update state from another component with vuex 【发布时间】:2018-12-03 04:58:18 【问题描述】:

例如,我有一个名为 App.vue 的文件,其中有导航抽屉组件。我有一个带有工具栏组件的名为 Home.vue 的文件。问题是我需要从 Home.vue 的工具栏组件切换导航抽屉状态(true 或 false)(此外,导航抽屉组件在 Home.vue 中呈现)。下面的代码不会返回任何错误,也不会更改导航抽屉的可见性。此外,如果在 store.js 中手动设置状态,导航抽屉会跟随它。有人可以帮忙吗?

store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store(
  state: 
    drawer: false
  ,
  mutations: 
    toggleDrawer: function(state) 
      return state.drawer = !state.drawer;
    
  ,
  actions: 
    toggleDrawer( commit ) 
      commit('toggleDrawer');
    
  ,
  getters: 
    active: (state) => 
      return state.drawer;
    
  
)

App.vue

<v-navigation-drawer v-model="drawer"> ... </v-navigation-drawer>

<script>
  import store from './store'
    export default 
      data: function() 
        return 
          drawer: this.$store.state.drawer
        
      
    
</script>

首页.vue

<v-toolbar-side-icon @click="$store.commit('toggleDrawer')"> ... </v-toolbar-side-icon>

<script>
  import store from '../store'
  export default 
    data: function() 
      return 
        drawer: this.$store.state.drawer // Seems like I don't need it here
      
    
  
</script>

【问题讨论】:

开发工具显示什么?点击图标时state.drawer 会更新吗? 【参考方案1】:

您可以使用导航抽屉的属性 permanent 而不是 v-model(以避免在 vuex 之外改变您的商店)并使用您定义的 getter active

App.vue:

<template>
  <v-app >
    <v-navigation-drawer :permanent="active">
      ...
    </v-navigation-drawer>
  </v-app>
</template>

<script>
  import  mapGetters  from 'vuex'
  export default 
    computed: 
      ...mapGetters([
        'active'
      ])
    ,
  
</script>

Home.vue:

<template>
  <v-toolbar-side-icon @click="toggle"> ... </v-toolbar-side-icon>
</template>

<script>
  export default 
    methods: 
      toggle() 
        this.$store.dispatch('toggleDrawer')
      
    
  
</script>

注意:当您在商店中定义了一个动作 toggleDrawer 时,您可以使用调度而不是提交。

现场示例here

【讨论】:

谢谢!我一回到家就按照你的建议去做! 嗯,谢谢,它可以工作,但是如果我绑定值,我需要在切换按钮上单击两次才能使抽屉出现。我检查了开发工具,发现关闭抽屉后,状态保持不变(表示为真),再次单击按钮后,它切换为假,下次单击时它变为真。有没有办法解决这个问题?【参考方案2】:

这是一篇较旧的帖子,但如果有人来寻找答案,这似乎可行。

来自 Vuex 指南,表单处理部分,Two-way Computed Property

我修改了Sovalina提供的codeandbox(谢谢!)link

另一种方式是使用v-model

<v-navigation-drawer v-model="drawer" app>

使用双向计算属性,而不是 mapGetters

<script>
    export default 
        computed: 
            drawer: 
                get () 
                    return this.$store.state.drawer
                ,
                set (value) 
                    this.$store.commit('toggleDrawer', value)
                
            
        
    
</script>

【讨论】:

以上是关于Vue 使用 vuex 从另一个组件控制和更新状态的主要内容,如果未能解决你的问题,请参考以下文章

Vue3 Vuex状态更改不更新计算值

Vue之vuex和axios

vuex 状态改变后更新所有客户端

Vue.js- Vuex 更新数组中的对象,内部状态未反映在组件 DOM 中

Vue--vuex的使用

了解Vuex状态管理模式的理解强化指南