在Vue.js中,对Array的变化侦测是通过拦截原型的方式实现的。也就通过对push,pop,shift,unshift,splice,sort,reverse,fill,copyWithin去改变数组自身内容的方法做拦截,从而响应。而product.status = this.productsState[product.productId];没有触发任何改变数组自身的被监听的方法,因此不会rerender。
刷新组件的key
$forceUpdate方法
刷新组件的key
1.这个key加在什么地方比较好?
加在this.productImages的父元素上就好。
若不涉及数据传递,也可以直接加在需要更新的element上。
2.用什么做key值?
现在是粗暴的+new Date()时间戳做key值的。
也可以用双向绑定的值作为key值,保证新旧key值不同就行。
3.key的原理是什么?
vue.js的虚拟DOM算法,在更新vNode时,需要从旧vNode列表中查找与新vNode节点相同的vNode进行更新,如果这个过程设置了属性key,过程就会快很多。
其他具体见上文。
$forceUpdate方法
只能在父组件调用这个方法,手动通知vue实例重新渲染。
// $forceUpdate源码 Vue.prototype.$forceUpdate = function () { const vm: Component = this if (vm._watcher) { vm._watcher.update() } } // update源码 /** * Subscriber interface. * Will be called when a dependency changes. */ update () { /* istanbul ignore else */ if (this.lazy) { this.dirty = true } else if (this.sync) { this.run() } else { queueWatcher(this) } }
1.$forceUpdate可以更新的原理分析
product.status = this.productsState[product.productId];以后,其实此时dep已经发生变化了,但是Vue.js数组响应式的实现由于是拦截原型链方法的方式,没有检测到这个变化,所以不会自动rerender,没有触发update。因此我们通过$forceUpdate的方式,调用包含dep的watcher上的update方法,从而做到rerender。
2.可以在子组件监听事件,父组件发送事件然后只刷新子组件吗?
不可以。
因为dep是父组件的watcher和dep,并不是子组件,是父组件的this.productImages没有被检测到并实时更新,并不是子组件的问题。