我对Vue还是陌生的,我很努力让组件在连接的数据更新后立即更新其内容。该组件将在重新渲染后立即显示更改的内容。
组件
Vue.component('report-summary', {
props: ['translation', 'store'],
watch: {
'store.state.currentModel.Definition': {
handler: function(change) {
console.log('Change detected', change);
},
deep:true
}
},
template: '<div>
'<div class="alert alert-secondary" role="alert">' +
'<h5 class="border-bottom border-dark"> {{ translation.currently_defined }}</h5>' +
'<div>{{ store.state.currentModel.Definition.length }} {{translation.elements }}</div>' +
'</div>' +
'</div>'
});
store
作为页面HTML中的属性传递:
<report-summary :translation="t" :store="store"></report-summary>
store
本身是Vuex.Store:
let store = new Vuex.Store({
state: {
t: undefined,
currentModel: undefined
},
mutations: {
storeNewModel(state) {
let model = CloneFactory.sealedClone(
window.Project.Model.ReportTemplateModel);
model.Header = CloneFactory.sealedClone(
window.Project.Model.ReportTemplateHeaderModel);
state.currentModel = model;
},
storeNewModelDefinition(state, definition) {
state.currentModel.Definition.push(definition);
}
}
});
在将任何数据存储在模型的currentModel
属性中之前,通过调用store.commit('storeNewModel');
初始化Definition
元素。
通过循环使用store.commit('storeNewModelDefinition')
更新定义的内容:
for (let c in this.$data.currentDefinition.charts) {
store.commit('storeNewModelDefinition', c);
}
调用store.commit('storeNewModelDefinition', c);
时,商店将按预期进行更新:
但是组件不会对更改的数据做出反应:
然后当我离开(通过更改隐藏嵌入式组件的视图)并再次导航到该视图时,内容已更新:
在“控制台”窗口中,我看到观察者在任何时间都没有被触发:
我在这里想念什么?非常感谢您提前睁开眼睛。
将watch
切换到事件总线侦听器也没有按计划进行。
这是EventBus的初始化:
window.eventBus= new Vue();
我将此添加到了我的组件中
created: function() {
window.eventBus.$on('report-summary-update', function() {
this.$nextTick(function(){ this.$forceUpdate(); });
});
}
并在列表中添加或删除元素后发出事件:
window.eventBus.$emit('report-summary-update');
在调试器中观察this.$forceUpdate();
设置断点时,我看到它也在被调用,但是UI仍将显示旧内容,而没有任何更改。我现在真的迷路了。
P.S。我将其交叉发布在Vue forum上,但是由于社区希望在这里获得一些反馈的希望很小。
答案 0 :(得分:2)
将数据推送到嵌套数组总是会导致组件无法更新的此类问题。
尝试向您的商店中添加吸气剂,并使用该吸气剂从商店中获取数据
let store = new Vuex.Store({
state: {
t: undefined,
currentModel: undefined
},
mutations: {
storeNewModel(state) {
let model = CloneFactory.sealedClone(
window.Project.Model.ReportTemplateModel);
model.Header = CloneFactory.sealedClone(
window.Project.Model.ReportTemplateHeaderModel);
state.currentModel = model;
},
storeNewModelDefinition(state, definition) {
state.currentModel.Definition.push(definition);
}
},
getters:{
definitions(state){
return state.currentModel.Definition
}
}
});
在您的组件中,您可以添加一个从商店获取数据的计算道具
Vue.component('report-summary', {
props: ['translation', 'store'],
computed: {
definitions(){
return store.getters.definitions
}
},
template: '<div>
'<div class="alert alert-secondary" role="alert">' +
'<h5 class="border-bottom border-dark"> {{ translation.currently_defined }}</h5>' +
'<div>{{ definitions.length }} {{translation.elements }}</div>' +
'</div>' +
'</div>'
});
更新(2019年11月30日)
如果上面的代码仍然不起作用,请将您的storeNewModelDefinition
突变更改为此:
storeNewModelDefinition(state, definition) {
// Create a new copy of definitions
let definitions = [...state.currentModel.Definition]
// Push the new item
definitions.push(definition)
// Use `Vue.set` so that Vuejs reacts to the change
Vue.set(state.currentModel, 'Definition', definitions);
}
答案 1 :(得分:1)
仅在您的EventBus实验上做一个笔记(您绝对应该尝试解决反应性问题,而不要尝试类似$forceUpdate
之类的技巧)
为什么您对EventBus的实验不起作用是因为使用匿名函数作为事件处理程序。看一下这段代码:
methods: {
onEvent() {
console.log(this)
}
},
mounted() {
// this.onEvent is method where "this" is bound to current Vue instance
this.$bus.$on("test", this.onEvent);
// Handler is anonymous function - "this" refers to EventBus Vue instance
this.$bus.$on("test", function() {
console.log(this)
});
}
this
被Vue本身显式绑定(由Vue自身绑定)到处理程序“存在”的Vue实例this
未显式绑定,因此最终类似于this == event bus Vue instance
。您可以使用闭包来解决此问题: mounted() {
let self = this;
this.$bus.$on("test", function() {
// self = "this" in context of function "mounted"
console.log(self)
});
}
JS中的 this
可能很棘手...
答案 2 :(得分:0)
摘自vuejs文档“深度反应”部分
数据对象中必须存在属性,以便Vue对其进行转换并使其具有反应性
这是一次性的Vue反应性警告。 Vue无法检测到属性的添加或删除。
以您的状态而不是currentModel: undefined
来添加您希望进行反应的所有属性,例如
currentModel: {
definitions:[]
}
然后从definitions
数组中添加或删除任何元素都会自动变为反应性。
您可以在文档中找到更多说明