2017-09-07 158 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来建议改变真相,但孩子并不直接修改事实。这将真相的所有管理保存在一个地方。