什么是数据劫持
加入有一个js文件内容如下:
var obj = {
x: 100,
y: 200,
}
Object.defineProperties(obj, {
x: {
set(){
console.log("You gonna update x, the vision will be changed.")
}
}
})
复制代码
当node运行这个js文件的时候不会有任何效果呈现。
但当在这个文件中加入一个变化的东西:
var obj = {
x: 100,
y: 200,
}
Object.defineProperties(obj,{
x: {
set(){
console.log("You gonna update x, the vision will be changed.")
}
}
})
obj.x ++
复制代码
console.log()里的话就会被打印出来。
基本原理是这个Object.defineProperties()函数能在数据更新的过程中捕获数据.
Object.defineProperties()这个函数是原生js。
最小量更新
写一个组件如下,实验一下Vue是否会在页面某个数据变化时在底层更新页面的其他数据。
手动在后台将下面的数字改成“哈哈”后点击x+1的按钮改变上面的数字,后台的“哈哈”保持不变。
这就是Vue特有的最小量更新算法,也叫DIFF算法。
当改变某个量时,Vue会检索template中的三个东西:
① 单个双打括号中是否有这个量;
② 指令中是否有这个量;
③ methods, computed和watch中是否有这个量。
只要符合以上其中一条,这个量都会得到更新。
关于单个双括号中是否有这个量,由于上图都是单个量在单个双括号内所以不能很好的说明这一点。以下再写一个有联动量的双括号:
这时点任何一个按钮“哈哈”都会更新为x+y的和。
下面进一步解释这个最少量更新算法的结算机制:
以上说明Vue视图更新遵循最小量更新原则,没有变化的视图Vue就不会让该视图所属的元素发生变化。
上面说到当改变某个量时Vue会检索单个双大括号中是否有这个量,在这个过程中Vue会进行求值,如果求得的值和原来的值是一样的,则不会发生更新。
【注意】由于Vue的这一机制,在使用时尽量避免混进对DOM的操作改而操作数据,否则容易触发这一机制导致更新无效。
React中也有DIFF算法,效率比Vue高,因为React没有指令系统,其所有数据都是立即求值而不像Vue会先进行一番数据检索。React的更新原理是将更新的DOM存入虚拟DOM中与旧的DOM进行DIFF再进行最少量更新,Vue则比React多了一步词法分析。
最小量更新的重要角色 - key
在使用v-for指令时常常会与key属性连用,否则某些情况下会出现编辑器报错,一般key属性的属性值为循环的item或者index,属性值为item代表的是每一项循环的item本身,属性值为index则代表的是每一项的顺序。
当涉及视图更新时,有没有key属性以及不同的属性值将会引发截然不同的结果。
没有key属性时更新不会触发beforeDestroy(),即原来的节点没有下树只是节点中的内容更新了。
有key属性并且属性值为item时更新则会触发beforeDestroy(),证明“α”的节点下树(消亡)了,新的“”的节点被创建并上树。
有key属性并且属性值为index时更新又不会触发beforeDestroy()了,即没有节点上下树。
所以当v-for循环涉及子组件循环时,key的属性值最好用item而不是index,否则会导致一些程序误判,当涉及一些AJAX等数据交互时也会阻断了组件与服务器之间的信息交换。使key的属性值为item的好处是能正确触发子组件的生命周期。