2017-09-07 155 views
0

我目前有一個對象的數組,我正在渲染到一個表。我試圖按照Vuejs提供的例子使用同一頁面上多個vues之間共享的「單一真相源」。總之,我試圖讓vue1.refresh()被觸發時,所有的vues更新他們的數據,當「單一真相源」被更新時。然而,self.surveys =調查;只更新vue1上的數據。VueJS:替換/更新陣列

注:我下面從https://vuejs.org/v2/guide/state-management.html

// The single source of truth 
var cache = { 
    data: [{...}] // Array of objects 
} 

var vue1 = new Vue({ 
    el: "#table", 
    data: { 
     surveys: cache.data // Points to the single source of truth 
    },   
    methods: { 
     refresh: function(){ 
      var self = this;     

      // After getting data back from an ajax call 
      .done(function(surveys) { 
       self.surveys = surveys; 
      }); 
     }, 
    } 
}); 

var vue2 = new Vue({ 
    el: "#table", 
    data: { 
     surveys: cache.data // Points to the single source of truth 
    },   
    methods: { 
     // Methods 
    } 
}); 
+1

看一看[Vuex](https://vuex.vuejs.org/) – Vanojx1

+0

你不應該改變另一個組件的數據,比如來自一個孩子的父母的數據。 –

回答

0

引導您將需要變異的陣列,而不是取代它。

Array.prototype.splice可以爲你做這個,如果你不想使用類似Vuex的東西,就像Vanojx1建議的那樣。

拼接需要特定的元素,而不是插入的完整數組。因爲你有一個你想使用的數組,並且你需要清除舊數組,所以語法有點奇怪...你通過這個,開始,要移除的計數(整個長度),然後元素添加(從新數組連接)。

Array.prototype.splice.apply([self.surveys, 0, self.surveys.length].concat(surveys)); 
+0

這不是這裏的問題。另外,更換陣列幾乎總是比保留反應性更好。 –

0

正如評論說之前,你可以使用vuex來完成你需要什麼,你需要每次傳遞diferent部件之間的數據,你可以這樣做與eventBus或通過props上下的組件之間。

當你有一個需要通過大量的數據和接收它,你可以使用vuex,首先你需要install it,然後你可以做這樣一個aplication:

你應該削減的方法出來,放置安裝(),它觸發時,該組件的負荷,我認爲這是你需要

var vue1 = new Vue({ 
    el: "#table", 
    data: { 
     surveys: cache.data // Points to the single source of truth 
    },   
    methods: { 

    }. 
    mounted() { 
     var self = this;     

     // After getting data back from an ajax call 
     .done(function(surveys) { 
     self.surveys = surveys; 
     }); 
    } 
}); 

,當你得到的迴應將它傳遞給vuex商店,你可以用這樣的突變做到這一點:

this.$store.mutation('handlerFunction', self.surveys) 

在vuex你需要有突變內handlerfunction

mutations: { 
    // appends a section to the tree 
    handlerFunction: (state, dataReceived) => { 
     //then you can do 
     state.surveys = dataReceived 
    }, 

然後在你的其他組件,您可以通過一個getter接受它,邏輯是更deaills相同手錶vuex,你有主邏輯這裏的連接。

希望它有幫助!

1

問題是,您正在用新的非共享對象替換先前分配給調查變量的共享Cache對象。和解決方案?不要試圖改變緩存對象。只需使用Vuex。 Vuex是簡單,真實的「Vue方式」解決方案。

// The single source of truth 
var cache = { 
    data: [{...}] // Array of objects 
} 

var vue1 = new Vue({ 
    el: "#table", 
    data: { 
     surveys: cache.data // Points to the single source of truth 
    },   
    methods: { 
     refresh: function(){ 
      var self = this;     

      // After getting data back from an ajax call 
      .done(function(surveys) { 
       self.surveys = surveys; // Problem is right here 

      }); 
     }, 
    } 
}); 

var vue2 = new Vue({ 
    el: "#table", 
    data: { 
     surveys: cache.data // Points to the single source of truth 
    },   
    methods: { 
     // Methods 
    } 
}); 

試試這個例子中,它就像你的代碼 - 不正確的方法:

var cache = { 
 
    key1: 'Value1' 
 
} 
 

 
var vue1 = new Vue({ 
 
    el: '#app1', 
 
    data: { 
 
    surveys: cache 
 
    }, 
 
    methods: { 
 
    replace() { 
 
     this.surveys = {key1: 'Replaced'} 
 
    } 
 
    } 
 
}) 
 

 
var vue2 = new Vue({ 
 
    el: '#app2', 
 
    data: { 
 
    surveys: cache 
 
    }, 
 
    methods: { 
 
    replace() { 
 
     this.surveys = {key1: 'Replaced'} 
 
    } 
 
    } 
 
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script> 
 

 
<div id="app1"> 
 
    Input for Vue1: <input type="text" v-model="surveys.key1"> 
 
    <button @click="replace">Replace</button> 
 
    <p>{{ surveys.key1 }}</p> 
 
</div> 
 

 
<div id="app2"> 
 
    Input for Vue1: <input type="text" v-model="surveys.key1"> 
 
    <button @click="replace">Replace</button> 
 
    <p>{{ surveys.key1 }}</p> 
 
</div>

然後嘗試這個例子,與Vuex,在那裏你可以自由更換「緩存對象「並且調換將影響其他實例:

const store = new Vuex.Store({ 
 
    state: { 
 
    cache: { 
 
     key1: 'Value1' 
 
    } 
 
    }, 
 
    mutations: { 
 
    replace (state) { 
 
     state.cache = {key1: 'Replaced'} 
 
    } 
 
    } 
 
}) 
 

 
var vue1 = new Vue({ 
 
    el: '#app1', 
 
    store, 
 
    computed: { 
 
    surveys() { 
 
     return this.$store.state.cache 
 
    } 
 
    }, 
 
    methods: Vuex.mapMutations([ 
 
    'replace' 
 
    ]) 
 
}) 
 

 
var vue2 = new Vue({ 
 
    el: '#app2', 
 
    store, 
 
    computed: { 
 
    surveys() { 
 
     return this.$store.state.cache 
 
    } 
 
    }, 
 
    methods: Vuex.mapMutations([ 
 
    'replace' 
 
    ]) 
 
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script> 
 
<script src="https://unpkg.com/[email protected]/dist/vuex.min.js"></script> 
 

 
<div id="app1"> 
 
    Input for Vue1: <input type="text" v-model="surveys.key1"> 
 
    <button @click="replace">Replace</button> 
 
    <p>{{ surveys.key1 }}</p> 
 
</div> 
 

 
<div id="app2"> 
 
    Input for Vue1: <input type="text" v-model="surveys.key1"> 
 
    <button @click="replace">Replace</button> 
 
    <p>{{ surveys.key1 }}</p> 
 
</div>

+0

第一個代碼片段在按鈕單擊時不會更新。此外,我所做的與https://vuejs.org/v2/guide/state-management.html上所描述的完全不同 – Neve12ende12

0

有Vue公司的兩個原則,這將幫助你在這裏:

  1. 在Vue公司,每data項目是真理的源泉。
  2. 只有data項目的所有者才能修改它。

在你的例子中,你有三個真相來源:你想成爲單一來源的那個來源,以及其他兩個來源。此外,你想成爲真相的源頭不是data項目,它是在Vue之外。

所以要開始,你應該有一個代表整個應用程序,並定義了代表應用程序級的狀態的任何數據的單一VUE:

new Vue({ 
    el: '#app', 
    data: { 
    cache: { 
     data: [...] 
    } 
    } 
}); 

您創建應該是應用程序的孩子兩個Vue對象Vue,也就是說,components

父母通過props告訴孩子什麼是真相。孩子可以通過向父母發出events來建議改變真相,但孩子並不直接修改事實。這將真相的所有管理保存在一個地方。