我目前有一个对象数组,我正在渲染到一个表。我试图按照Vuejs提供的例子来使用"单一的事实来源"在同一页面上的多个vues之间共享。
总的来说,我试图在触发vue1.refresh()的时候使用它,所有的vues都会在"单一事实来源时更新他们的数据"已更新。但是,self.surveys =调查;仅更新vue1上的数据。
注意:我正在关注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
}
});
答案 0 :(得分:1)
问题是,您正在使用new而非共享对象替换先前分配给survey变量的共享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/vue@2.4.2/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这个例子,你可以自由地替换“缓存对象”,并且replacint会影响其他实例:
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/vue@2.4.2/dist/vue.min.js"></script>
<script src="https://unpkg.com/vuex@2.4.0/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>
答案 1 :(得分:0)
您需要改变数组,而不是替换它。
Array.prototype.splice可以为您执行此操作,如果您不想按照Vanojx1的建议使用Vuex之类的内容。
Splice需要特定的元素,而不是插入的完整数组。因为你有一个你想要使用的数组,你需要清除旧数组,语法有点奇怪......你传递这个,开始,删除的数量(整个长度) ,然后添加元素(从新数组连接)。
Array.prototype.splice.apply([self.surveys, 0, self.surveys.length].concat(surveys));
答案 2 :(得分:0)
正如之前的评论中所述,您可以使用vuex来完成您的需求,每当您需要在不同组件之间传递数据时,您可以使用eventBus或上下传递props来执行此操作组件之间。
如果您的应用程序需要传递大量数据并接收它,您可以使用vuex,首先需要install it,然后您可以这样做:
你应该把方法切掉并放置已安装的(),它会在组件加载时触发,我认为这是你需要的
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中你需要在变异中包含处理函数
mutations: {
// appends a section to the tree
handlerFunction: (state, dataReceived) => {
//then you can do
state.surveys = dataReceived
},
然后在你的另一个组件中,你可以通过一个getter接收它,逻辑与更多deaill相同的watch vuex,你有这里的主要连接逻辑。
希望它有所帮助!
答案 3 :(得分:0)
Vue有两个原则可以帮到你:
data
项都是真理的来源。data
项目的所有者才能对其进行修改。在您的示例中,您有三个事实来源:您想要成为单一来源的那个,以及另外两个从中初始化的来源。而且,你想成为真理之源的那个不是data
项,它在Vue之外。
首先,您应该有一个代表整个应用程序的Vue,并定义代表应用程序级状态的任何数据:
new Vue({
el: '#app',
data: {
cache: {
data: [...]
}
}
});
您创建的两个Vue
对象应该是应用程序Vue
的子对象,也就是components。
父母通过props告诉孩子真相是什么。孩子可以通过向父母发出events来建议改变真相,但孩子不会直接修改真相。这使得所有真相管理都集中在一个地方。