c语言sscanf函数的用法是什么
275
2022-09-16
Vue核心⑨(数据监测原理)
文章目录
问题引入如何实现针对对象进行数据监测Vue.set()的使用如何实现针对数组进行数据监测数据监测总结
问题引入
我们前面知道只要data中的数据发生变化,那么Vue会重新解析模板更新数据。那么这一定是决定的吗?我们可以看看下面的例子:
我们借用原来的列表案例,对其中的一项进行修改:
如果只是对其中对象的属性进行修改,是奏效的:
而如果是对其中的对象整体修改,会发现不奏效:
如何实现针对对象进行数据监测
在前面我们说到数据代理的时候,我们当时说Vue会将data中的数据放到_data中去,然后再将_data中的数据进行代理。其实在Vue将data中的数据放到_data之前,Vue对data中的数据进行了加工,而这个加工的步骤就是Vue实现数据监测的关键。
我们可以来验证一下: 对于如下代码(简单的在data中放了两个数据):
我们可以看到:
在vm._data中我们可以发现里面的东西并不完全跟data中的一样,说明确实做了一个加工。而这个加工的内容就是多出来的方法。也就是说Vue为每一个数据添加了get和set方法。
Vue通过这个加工就做成了响应式(图中的reactive其实就是响应的意思)。当我们修改数据的时候,就会执行其setter方法,而这个setter方法里面就有一个调用。他让我们的模板重新解析。
完整流程: 改变数据 => 调用setter => 重新解析模板 =>生成新的虚拟DOM => 新旧DOM对比 =>更新页面
其实我们可以尝试粗略的去实现一下数据监视:
如上的代码只考虑到了一层的情况,也就是说如果出现对象里面还有属性的情况,它发生改变我们是监视不到的。
Vue底层使用递归,它会一直往下找,直到找到某一个东西不再是对象。
例如,如果data是这样的:
let data = { name:'CSDN', address:'北京', a:{ b:1 } }
使用如上代码是提供不了b的getter和setter的:
同时Vue里面还使用了数据代理,上面的代码是没有用到的。我们修改数据只能通过_data,而不能直接通过data如果我们将一个对象藏在了数组里面,Vue也可以把它找出来,并提供相应的getter和setter:
Vue.set()的使用
我们现在有一个需求,人物的性别不能确定,我们想要在后期添加,并且能让页面显示。我们的思路是直接添加任务的性别属性,这样就能显示出来了。但这样真的可以吗?
注意: Vue不会显示一切为Undefine的值 我们可以衍生一下假设a为对象,b为属性(并不存在的)。a.b如果a存在b不存在,Vue不会报错,并且不显示undifined 如果直接访问b,b不存在,则Vue会报错。
然后我们给性别属性赋值:
发现页面并没有发生变化:
我们查看vm可以发现,导致页面没有变化的原因是因为新添加的性别属性根本没有getter和setter:
也就是说后添加的属性Vue是不会为其做响应式的。也就是说我们需要响应式的数据最好一开始就在源码中定义好。当然Vue也给我们提供了方法去解决后期添加的数据没有响应式的问题,它就是Vue.set()
我们可以尝试一下:
同时这种方法在vm身上也有一个,它的名字叫$set(),我们也可以试一下:
但是这个方法也有局限性!例如:
使用这个方法vm以及vm身上的根数据不允许作为target。也就是说只能在data中的对象中才能添加属性,直接在data中加不行。
如何实现针对数组进行数据监测
我们在以上案例的基础上,为student中添加一个属性hobby,其值为数组:
我们接下来将其爱好用列表进行呈现,代码如下:
接下来我们对hobby列表中的其中一项进行修改,发现页面并没有进行更新。
我们查看vm,发现Vue并没有为数组中的每一项配置getter和setter方法:
那么我们怎么能让Vue知道我们修改了数组中的数据呢?
其实Vue中规定了只有使用如下的几种方法对数组进行修改的时候,这种变化才能被监测得到:
push() 向数组的末尾添加元素pop() 删除数组的最后一个元素shift() 删除数组的第一个元素unshift() 在数组的开头添加新元素splice() 用于添加和删除元素sort() 对数组进行排序reverse() 对数组进行反转
例如:
那么Vue是如何检测到我们使用了这种办法的呢?这要依赖于一种独特的包装技术 – 包装数组身上的常用的修改数组的方法。
其实我们使用的push,与我们Array.push不是一个方法:
我们原来使用的push是沿着原型链往上找,在原型对象上找到的push。而这里的push是Vue给我们写的push,Vue在这个push方法中为我们做了两件事:
调用正常数组的push方法重新解析模板,生成虚拟DOM········
数据监测总结
代码如下:
什么是数据劫持? 就是将data中的每一个属性都遍历了一遍,形成getter、setter的形式,这种行为就是数据劫持。 例如我们修改一个属性,会立马被setter劫持到。劫持之后它会正常的帮我们修改数据,另一个就是帮我们重新解析模板。 数据劫持和数据代理都离不开Object.defineProperty()
总结:
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~