2017-08-13 38 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(狀態,項目)實現或如何傳遞項目標識的方式 –