2017-08-13 117 views
4

让我们说我有以下三种:Vue.js + Vuex:如何改变嵌套的项目状态?

[ 
    { 
     name: 'asd', 
     is_whatever: true, 
     children: [ 
      { 
       name: 'asd', 
       is_whatever: false, 
       children: [], 
      }, 
     ], 
    }, 
], 

树下键“树”通过Vuex存储在模块中,并循环通过与以下称为“递归项目”递归成分:

<li class="recursive-item" v-for="item in tree"> 
    {{ item.name }} 

    <div v-if="item.is_whatever">on</div> 
    <div v-else>off</div> 

    <ul v-if="tree.children.length"> 
     <recursive-item :tree="item.children"></recursive-item> 
    </ul> 
</li> 

现在我想切换项目的财产“is_whatever”,所以我附上一个监听

<div v-if="item.is_whatever" 
     @click="item.is_whatever = !item.is_whatever">on</div> 
    <div v-else>off</div> 

当我点击它,它的工作原理,但发出以下

"Error: [vuex] Do not mutate vuex store state outside mutation handlers." 
[vuex] Do not mutate vuex store state outside mutation handlers. 

我该如何在没有这个错误的情况下实现它?我无法看到如何派发一个动作或将事件发送到树的顶端,因为它是嵌套的和递归的,所以我没有获得特定项目的路径,对吧?

回答

0

当晚晚些时候与其他一些开发人员进行了磋商之后,我们几乎没有找到如何实现它的方法。由于数据嵌套在树中,我以递归方式访问节点,因此我需要获取特定节点的路径,例如将节点的索引作为属性传递,然后添加子索引,同时重复在每个节点中递归地,或只传递一个节点的id,然后在动作中运行递归循环来切换其属性。

更优化的解决方案可以使数据结构扁平化,从而避免了递归的需要。该节点可以通过一个id直接访问。

1

现在你通过调用item.is_whatever = !item.is_whatever直接更改状态的对象,你需要做的是建立一个突变的功能,将执行该操作,为您保证正确的反应是什么:

const store = new Vuex.Store({ 
    state: { /* Your state */ }, 
    mutations: { 
    changeWhatever (state, item) { 
     const itemInState = findItemInState(state, item); // You'll need to implement this function 
     itemInState.is_whatever = !item.is_whatever 
    } 
    } 
}) 

然后,你需要将this.$store.commit('changeWhatever', item)作为您的视图中的一项行为公开,该行为将通过点击触发。

+0

这就是发出警告的原因,但我意识到了这一点(请参见最后一段)。问题是数据有一个树形结构,我不知道如何通过一个动作或一个提交切换特定的项目...所以,你是对的,但回答不同的问题 - 我对findItemInState(状态,项目)实现或如何传递项目标识的方式 –