首頁 文章 vue深入响应原理

vue深入响应原理

2021-12-06 23:31  瀏覽數:530  來源:小键人1828154    

现在是时候深入一下了!vue最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的javaSc
ript对象。而当你修改他们的时候,视图会进行更新。这使得状态管理非常的简单直接,不过理解其工作原理同样重要,
这样你就可以避开一些常见的问题。在这个章节,我们将研究一下vue的响应系统底层的细节。 如何追踪变化?当
你吧一个普通的javaScript的对象传入vue实例为data选项,vue将遍历此对象所有的property
,并使用Object.defineProperty将这些property全部转化为getter/setter。
Object.defineproperty是es5中一个无法shim的特性,这也是vue不支持ie8以及更低版
本的浏览器的原因。这些getter和setter对用户来说是不可见的,但是在内部他们却可以让vue能追踪依赖,
在property被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对getter/se
tter的格式化并不同,所以建议安装vue-detools来获取对检查数据更加有好的界面。每个组件实例都对应这
一个watcher实例,他会在组件渲染的过程中把接触到得数据property记录为依赖。之后当依赖项的sett
er触发时,会通知watcher,从而使他关联的组件重新渲染。检测变化的注意事项。由于javascript的限
制,vue不能检测到数组和对象的变化,尽管如此我们还是有一些办法来回避掉这些限制并保证他们的响应性。对于对象:
vue无法检测到property的添加和移除。由于vue会在初始化实例时对property执行getter/S
ETTER转化,所以property必须在data对象上存在才能让vue将它转化为响应式的。 例如:var v
m=new Vue({data:{a:1}})vm.b=2对于已经创建的实例,vue不容许动态添加根级别的响应
式property。但是,可以使用vue.SET(object,propertyName,value)方法向嵌
套对象添加响应式property。例如,对于:Vue.set(vm.someObject,'b',2)您还可以
使用 vm.$set实例方法,这也是全局Vue.set的方法的别名。有时你可能需要为已有对象赋值多个新prop
erty,比如使用 Object.assign()或者 _.extend()。但是,这样添加到对象的新的pro
perty不会触发更新。在这种情况下,你应该用原对象与要混入进去的对象的property一起创建一个新的对象。
//代替`Object.assign(this.someObject,{a:1,b:2})`this.some
Object=Object.assign({},this.someObject,{a:1,b:2})对于数组V
ue不能检测到以下数组的变动:1,当你利用索引直接设置一个数组项时,例如:vm.items[indexOfIt
em]=newValue2.当你修改数组的长度时,例如:vm.items.length=newLength举个
例子:var vm=new Vue({ data:{ items:['a','b','c']}
})vm.items[1] = 'x' //不是响应性的vm.length=2 //不是响应性的为了解决第一
类问题,以下两种方式都可以实现vm.items[indexOfItem]=newValue 相同的效果,同时也
将在响应式系统内触发状态更新:Vue.set(vm.items,indexOfItem,newValue)Vu
e.items.splice(indexOfItem,1,newValue)你也可以使用vm.$set实现方法
,该方法时全局方法Vue.set的一个别名:vm.$set(vm.items,indexOfItem,newV
alue)为了解决第二类问题,你可以使用splice:vm.items.splice(newLength)声明
响应式Property由于Vue不允许动态的添加根级响应式property,所以那必须在初始化实例前声明所有的
property,哪怕只是一个空值。var vm=new Vue({data:{ message:''}t
emplate:'<div>{{message}}'}),vm.message='hello'如果你未在dat
a中声明message,vue将警告你渲染函数正在视图访问一个不存在的property。这项的限制在背后有其他
技术原因的,他消除了在依赖项耿总系统中的一类边界情况,也使Vue实例能更好地配合类型检查系统工作。但与此同时在
代码可维护性方面也有一点重要的考虑。data对象就像组件状态的结构schema。提起那声明所有的响应式prop
erty,可以让组建代码在未来修改或其他开发人员阅读时更易于理解。异步更新队列。可能你还没有注意到,Vue在更
新Dom时时异步执行的。只要侦听到数据变化,Vue将开启一个队列,并缓冲在同一时间循环中发生的所有数据变更。如
果同一个watcher被多次触发,只会别推送到队列中一次。这种缓冲时去掉重复数据对于避免不必要的计算和DOM操
作时非常重要的。然后在下一个的事件循环“tick”中,Vue刷新队列并执行实际(已经去重)工作。Vue在内部对
异步队列尝试使用原声的Promise.then、MutationObserver和setImmediate,如
果执行环境不支持,则会采用setATimeout(fn,0)代替。例如,当你设置 vm.someData= '
new value' ,该组件不会立即重新渲染。当刷新队列时,组件会在下一次事件的循环“tick”中更新。多数
情况我们不需要关心这个过程,但是如果你想给予更新后的DOM状态来做点什么,这就可能会有些棘手。虽然VUe.js
通常鼓励开发人员使用“数据驱动”的方式思考,避免直接接触DOM,但还是有时我们必须那么做。为了在数据变化后等待
Vue完成更新DOM,可以在数据变化之后立即使用Vue.newTick(callback)。这样的回调函数将在
Dom更新完成后被调用。例如:



聲明:以上文章均為用戶自行添加,僅供打字交流使用,不代表本站觀點,本站不承擔任何法律責任,特此聲明!如果有侵犯到您的權利,請及時聯系我們刪除。

字符:    改为:
去打字就可以设置个性皮肤啦!(O ^ ~ ^ O)