当前位置:首页 » 《随便一记》 » 正文

深入理解Vue响应式原理

16 人参与  2022年07月03日 17:22  分类 : 《随便一记》  评论

点击全文阅读


前言

Vue响应式原理是Vue最独特的特性之一,当数据模型进行修改时,视图就会进行更新,这使得状态管理简单直接,但是其底层的细节还是需要我们深入学习理解,这样遇到一些问题我们才能快速进行定位,并解决;下面我将带大家由浅入深,逐步理解Vue的响应式原理;
在这里插入图片描述

文章の目录

前言如何监测数据的变化注意事项对象数组 写在最后

如何监测数据的变化

要想准确响应数据的变化,首先需要精确及时的监测数据的变化,Vue检测数据的变化核心还是通过Object.defineProperty();下面通过实例为大家详细阐述Vue检测数据变化的过程,代码示例如下:

<script type="text/javascript" >let data = {name:'xizhutao',address:'安徽',}//创建一个监视的实例对象,用于监视data中属性的变化const obs = new Observer(data)console.log(obs)//准备一个vm实例对象let vm = {}vm._data = data = obsfunction Observer(obj){//汇总对象中所有的属性形成一个数组const keys = Object.keys(obj)//遍历keys.forEach((k)=>{Object.defineProperty(this,k,{get(){return obj[k]},set(val){console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)obj[k] = val}})})}</script>

以上代码检测数据变化的思路如下:
一、封装一个Observer构造函数,接收一个data数据对象,通过Object.keys()方法,将接收到的数据对象中的属性存放到一个数组中,然后调用forEach()方法对数组进行遍历,用Object.defineProperty()给this即Observer实例对象添加数组中的每一项属性;
二、通过get、set方法监测数据的操作,一旦Observer构造函数的实例对象上的属性被访问,get函数就会被调用,返回data数据中的属性值,同样的Observer构造函数的实例对象上的属性被修改了,data数据中的属性值也实现了修改;这就是Vue监测数据变化的原理;

注意事项

对象

Vue不能监测对象的Property的添加和删除,在监测数据变化原理中讲到,在Vue初始化实例对象时,会将data对象中的属性存到数组中进行遍历,然后调用Object.defineProperty()给属性添加get , set方法监视data对象中属性的变化,因此如果我们在初始化实例对象后,给Vue实例添加属性,并不会给添加的属性添加对应的get、set方法,导致添加的属性并不是响应式的;如果你还不理解,请看以下示例代码:

var vm = new Vue({  data:{    a:11  }})// vm.a 是响应式的vm.b = 22// vm.b 是非响应式的

以上代码中的a属性在初始化实例对象时就有,因此会生成相对应的get、set方法,然而b属性是在初始化vm实例后添加的属性,因此并没有生成相对于的set和get方法;导致属性b并不是响应式的;
针对以上问题我们可以使用Vue.set(object, propertyName, value)或者vm.$set ( target,propertyName/index,value)方法解决,但是此方法只能给嵌套的对象添加属性,不能给vm或vm的根数据对象添加响应式属性;
代码示例如下:

//someObject为嵌套在data数据对象内的一个对象Vue.set(vm.someObject, 'b', 22)vm.$set(this.someObject,'b',22)

⚠注意:set方法不能给vm或vm的根数据对象设置属性,只能给跟数据对象中嵌套的对象设置属性❗❗❗

数组

Vue不能监测以下数组的变动:1、通过索引号修改数组的对应值,修改后的值不是响应式的;2.通过length修改数组长度时,数据不是响应式的;示例如下:

var vm = new Vue({  data: {    items: ['a', 'b', 'c']  }})vm.items[1] = 'x' // 不是响应性的vm.items.length = 2 // 不是响应性的

为了解决以上通过索引添加的数据不是响应式的,可以使用以下方法解决:
1、Vue.set(vm.items, indexOfItem, newValue)
2、vm.$set(vm.items, indexOfItem, newValue)
3、vm.items.splice(indexOfItem, 1, newValue)
为了解决通过length属性改变数组长度也是响应式的,可以使用以下方法:
vm.items.splice(newLength)
代码示例如下:

var vm = new Vue({  data: {    items: ['a', 'b', 'c']  }})Vue.set(vm.items , 0 , 'aa') // 响应性的vm.$set(vm.items , 0 , 'aa') // 响应性的vm.items.splice(0 , 1 , 'aa')//响应性的//通过lengthvm.items.splice(2)//响应性的

更详细的信息请查看Vue.js官网:深入理解响应式原理

写在最后

?(❁´◡`❁)您的点赞?➕评论?➕收藏⭐是作者创作的最大动力?


点击全文阅读


本文链接:http://zhangshiyu.com/post/42585.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 掉马后,前任跪求我的特种兵司机放过他超长版_苏振邦陈明苏微微爆火全网_小说后续在线阅读_无删减免费完结_
  • 比赛那天,他为青梅将我绑架抽血无广告_贺擎盛夏小姐节选_小说后续在线阅读_无删减免费完结_
  • 春尽人不归结局阮彦初骆澜月完本_春尽人不归结局(阮彦初骆澜月)
  • 独家姜甜甜无删减(农家福星:捡来的奶团旺全家)(姜甜甜)TXT免费版阅读
  • 最后一页没说再见晋江金榜_时砚江疏桐桐桐无错版_小说后续在线阅读_无删减免费完结_
  • 体检前,我放任所有体育生误食兴奋剂小众冷门_赵津川沈梦青梅后续+番外_小说后续在线阅读_无删减免费完结_
  • 热门章节_笔趣阁(前路漫漫,承担了无数梦想)前路漫漫,承担了无数梦想小说(谢鹤书萧清禾)章节在线阅读
  • 农家福星:捡来的奶团旺全家姜甜甜小说无删减阅读无干扰(姜甜甜)番外+续集
  • 宋颜泽江晚吟续集(宋颜泽江晚吟)终极反转(雾隐繁花情已逝)全篇一口气阅读
  • 女儿玩了一百次云霄飞车,老公和童颜芭比coser嗨爆鬼屋小众冷门_老公云霄飞车祁晓筱快手热门_小说后续在线阅读_无删减免费完结_
  • 在品茶大会承认我是废物后,假千金却急了最新章节_白露露露露付凌逸校园甜文_小说后续在线阅读_无删减免费完结_
  • 完结文我们终将背叛命运+后续列表_完结文我们终将背叛命运+后续(温妤陆北屿)

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1