field list什么意思_从源码中学Vue(六)「解密」为什么操作数组的方法也会触发视图更新...

欢迎来到我的《从源码中学Vue》专题系列文章,更多精彩内容持续更新中,欢迎关注 :)

d29e4170d1f41f71f90aa10d448b454a.png

上一章节我大概分析了下在Vue中的 Watcher、Observer、Dep三者的关系,以及如何检测数据变化去更新视图的,以及通过源码分析了vue在初始化的时候是如何响应模板数据。

本章目标

  • Object.defineProperty存在的问题
  • 为什么在我们操作数组的时候可以实现视图更新
  • vue中数组劫持仍然存在的问题

Object.defineProperty存在的问题

我们都知道,在Vue2.x中,内部实现的数据响应是通过Object.defineProperty来实现的,其实这个API是存在一些问题的。

比如,它不能兼听到数组的变化,什么意思呢?我来举个例子。

7937be484f22456dd77b9ccf55cfd3e9.gif

我通过Object.defineProperty定义了一个简单的方法,当我们的key为数组的时候,我们直接通过obj.list.push修改数组的时候,可以看到,我们的set方法并没有被触发。

我们再来通过vue来看下我们修改list的时候会发生什么?

99d8008d9327ea8b5113a2013781bc5d.gif

可以看到,在vue中,我们对data下的list添加元素的时候,视图被更新了,也就是说,vue中操作数组的时候会发生数据响应。

a2800e02727462380d0ec4afb03f07ca.png

结论:原生的Object.defineProperty不能劫持数组push等操作,但是vue却可以?

为什么在我们操作数组的时候可以实现视图更新

那么说明Vue内部一定做了一些兼容处理!

带着这个问题,跟我去源码中找找答案吧!!

那么在数据劫持的目录下很容易找到一个array.js的文件,我们打开它看看

文件目录:node_modulesvuesrccoreobserverarray.js

它长这样!

41a917f655b7b3f1a7b78856b071e67e.png

先不用细看,看到

57855b4a45aa0eb436befc5323787f61.png

这一坨代码,我们就知道,vue针对这些方法做了处理。

那好,我们接下来具体分析下vue具体做了什么?

d96eaaac5a2c52aaa80eb65ea4d4e986.png

我们将原生的Array上的原型复制出来存储到了arrayMethods变量中。之所以要复制一个原型对象出来,是不能响应原生的数组的特性。

beed3cb6c2fdbc5a431fc8726d6dd779.png

这有一个def方法,我们去找下它的定义。

目录:node_modulesvuesrccoreutillang.js

94de7fc58b64b34b7986060d56cefadc.png

它就是给一个Object对象添加Object.defineProperty,然后主要看第二个参数。value,通过调用我们知道,我们传入的实参是一个function 。

什么意思呢,这里我们就能够兼听到当数组的原生方法被触发后的回调。我再举个例子

3488e6e4cb0ce3835ad9f494abbb84ba.gif

这个示例中,我兼听了原生数组的push方法,当有push操作的时候,可以触发一个回调函数。

那么到这里,相信vue的数组响应原理应该就明白了吧。

到这里还没完,我们接着往下看

a3b213ebbe18e4898dfa6f81480f7001.png

我圈出来的是为了实现数组原生的方法的执行。这里面的this就是指向的我们的要兼听的数据对象

在这个方法的最后,源码调用了ob.dep.notify()方法,那么这个ob是怎么来的呢?

 const ob = this.__ob__

这个对象我们可以在Observer类的中找到。

4b8e401f40e833486fe306f399272e34.png

我们给value定义了一个__ob__的属性,然后赋值为this,这里面的this指向的是Observer对象。所以我们在最后可以调用ob.dep.notify()方法。

最后再来看这一坨代码

1899e196c13cba16e927f0ac455d0326.png

定义了一个inserted变量,它表示的是是否为添加。我们知道,给数组添加元素的方法有三个,push,unshift,splice。然后调用Observer兼听数组的observeArray方法。

splice这个方法当有第三参数的时候,可以视了给数组添加项。

思考一下,为什么要兼听数组的添加的方法呢?

其实前面也有提到过。比如,我们添加数组的项可能为一个对象,或者数组,如果这是些那么我们的Observer将要继续兼听这个对象,给这个对象添加get和set方法。

举个例子

b4842fdbb53834e8459b0ed153e30f0d.gif

当我们给数组添加成一个对象的时候,vue这时候也会劫持对象,我们可以看到对象的a已经被设置了get和set。

vue中数组劫持仍然存在的问题

在vue中,有一种情况下数组是不能被劫持的,那就是当我们手动通过索引改变数组的某一项的时候,不会触发视图的更新。比如这样:

ae9d6d07cdbba2144461b9da254f301f.gif

视图并没有变化

这个解决办法就是重新给list赋值 ,我们知道数组的concat和slice方法都可以返回一个全新的数组。我们可以这样做。

vm.list = vm.list.concat([]);  或者vm.list = vm.list.slice(); 
ccb7aeb522809a4ed04c0863eccd0729.gif

到这里,Vue劫持数组的原理基本上就分享完了。


总结:

  1. 原生的 Object.defineProperty并不能劫持数组的变化。
  2. vue是通过重写了数组的Array原型上的方法,实现了数据的劫持
  3. 当我们通过索引去修改数组的时候,可以调用数组的slice和concat方法来手动实现视图更新
  4. Object.defineProperty可以实现JS内部函数的劫持。

这里是畅哥聊技术 《从源码中学Vue》系列文章,更多精彩内容持续更新中,敬请期待。

未完待续。。。

weixin_39683021
关注 关注
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
vue.js移动数组位置,同时更新视图方法
11-26
使用vue.js v-for绑定若干个选项,需要对选项进行排序上下移动操作。 需要对options里面数组的位置进行交换,通常是这样来写: 假设向前移动一个: var index = this.options.indexOf(option); //获取当前选项对象...
mounted钩子函数_详解 vue 生命钩子函数
weixin_44096391的博客
10-26 771
vue生命周期
vue函数如何调用其他函数?_从中学Vue(一)生命周期中的钩子函数的那点事儿...
weixin_39643255的博客
11-20 670
欢迎来到我的《从中学Vue》专题系列文章,更多精彩内容持续更新中,欢迎关注 :)Vue作为当下前端最流行的框架之一,在国内占绝对的优势。所以接下来我们一起来学习它吧!我不像其它人一样去教大家怎么去使用vue的API,那些官网有详细的教程,而我将带着大家一起进入它的码看看vue究竟做了什么?所以,接下来我希望正在阅读的你具有以下基础较好的JS基本功。有JS面向对象基础,不清楚的可以去看下我上...
vue函数如何调用其他函数?_详解 vue 生命钩子函数
weixin_39689687的博客
11-20 2056
好,接下来让我们学习一下vue的生命周期, vue 的生命周期也叫钩子函数,是vue从创建到销毁所触发的函数,1.beforeCreate(){console.log("创建之前");}, beforeCreate(),这是第一个生命周期函数, 表示实例完全被创建出来之前, 执行它,此时data和methods中的数据和方法都还没有被初始化,在这里是获取不到data中的数据的,console报...
Vue ------ 生命周期,执行钩子函数详解
qq_41962068的博客
10-06 366
Vue生命周期 每个 Vue 实例在被创建时都要经过一系列的初始化过程,例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机。 生命周期图示 生命周期钩子 所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算 beforeCreate 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之
入门C语言20问20答
张巧龙的博客
07-25 771
1 程序的编译及链接是怎样一个过程?2编写第一个简单的C语言程序3 C语言是强类型的语言,这是什么意思?任何程序都要处理数据,计算机可以处理的数据有多种类型。在C语言程序中,用来保存...
vue.js中$set与数组更新方法
01-21
当然vue中给了解决方法,就是使用 Vue.set, vm.$set(Vue.set的变种写法)或者 splice,caoncat等修改数组,同时也将触发状态更新: ex: 所以如果在实例创建后添加新的属性到实例上,则不触发更新。 ps:现在有两...
浅析vue.js数组的变异方法
12-29
Vue 包含一组观察数组的变异方法,所以它们也将触发视图更新。这些方法如下: push() pop() shift() unshift() splice() sort() reverse() 都有什么功能?动手试验了一下: <body> push方法: ...
vue 中一个函数中调用另一个函数
weixin_38673922的博客
06-08 3114
函数调用
vue中一个组件怎么调用另一个组件中的函数
m0_68094390的博客
05-14 2022
在上面的例子中,通过在组件上添加ref属性来定义组件的引用。然后在调用函数的方法中,使用this.$refs.componentA来获取组件实例,并直接调用组件中的函数componentAFunc()。在Vue中,如果一个组件需要调用另一个组件中的函数,可以使用$refs属性来获取组件实例,并直接调用组件中的函数。
vue中在一个函数中调用另外一个函数
qq_40801969的博客
04-22 5557
vue中在一个函数中调用另外一个函数 this.$options.methods.函数名.bind(this)();
mounted钩子函数_vue生命周期钩子函数的正确使用方式
weixin_39572168的博客
12-20 1367
先上图vue的生命周期遇到的一个问题在我的项目中,常用的生命周期钩子函数一直都是mounted,对于大部分情况,都是屡试不爽、捷报频传~但是在前几天却遭遇了一个意外,我在mounted中获取后台数据并更新data,在template中把data.fullname与一个p元素的innerHTML绑定,这是一个简单到不能再简单,普通到不能更普通的操作,打开浏览器一看,完美!fullname的数据正常显...
Vue中的生命周期钩子函数mounted方法及其在项目开发中的作用
最新发布
qzh88888888的博客
09-27 1607
这个方法提供了一个重要的时机,在DOM元素渲染完毕后执行一些必要的操作。4、执行其他初始化操作:在项目开发中,还可以利用mounted方法执行其他一些初始化操作,例如动态计算DOM的尺寸、初始化动画效果、读取本地存储等。1、执行异步操作:在mounted方法中,可以执行一些需要依赖DOM元素的异步操作,例如发送网络请求、获取数据、初始化插件或库等。2、异步操作的处理:由于mounted方法是在DOM渲染完毕后触发的,如果存在需要较长时间的异步操作,建议在操作开始前显示加载状态或占位元素,以提高用户体验。
vue2的Mounted和vue3的onMounted,这两个钩子有何不同?
热门推荐
杜永康的博客
06-13 1万+
钩子是通过 setup函数来使用的,它必须在组件实例创建之前调用,并返回一个对象,该对象包含组件实例中需要使用的数据、方法和生命周期钩子等。钩子中的函数在组件挂载到 DOM 上之后执行,与 Vue 2 的 mounted 钩子相同,因此在该钩子中可以访问到组件的 DOM 元素。如果需要访问组件实例中的数据和方法,可以使用。钩子是在组件实例被挂载到 DOM 上之后才被调用的,因此在该钩子中可以访问到组件的 DOM 元素。钩子在组件的子组件被挂载之前被调用,因此如果需要在子组件中访问到父组件的数据,可以在。
VUE如何在另一个函数中调用另一个函数运算后的结果
kana_yonk的博客
03-09 2757
菜鸟教程:VUE如何在另一个函数中调用另一个函数运算后的结果
vue--mounted cannot read property 'name' of undefined"
liyuling52011的博客
09-09 2285
1.钩子函数  钩子函数是Windows消息处理机制的一部分,通过设置“钩子”,应用程序可以在系统级对所有消息、事件进行过滤,访问在正常情况下无法访问的消息。钩子的本质是一段用以处理系统消息的程序,通过系统调用,把它挂入系统。(百度百科) 2.相对于前端来讲  对于前端来说,钩子函数就是指再所有函数执行前,我先执行了的函数,即 钩住 我感兴趣的函数,只要它执行,我就先执行。 3.vue中的mo...
vue函数如何调用其他函数?_python学习11-1-函数创建、调用及参数传递
weixin_39875503的博客
11-19 435
在python中中,为了代码多次使用,且做到模块化管理,最有效的方式是将其定义为函数,在需要使用时,随时调用即可。函数的创建和调用a. 定义函数:使用def关键字def functionname([parameterlist]):['''comments'''][functionbody]例子:def greet_user(): #即使函数没有参数,也必须保留一对小括号'''显示简单的问候语'''...
vue2.0的生命周期和钩子函数深度解析
关注最新技术问题并持续维护更新
04-18 2261
一、理清Vue的生命周期和钩子函数
mounted钩子函数_钩子函数是什么
weixin_42338883的博客
01-03 762
为何有此一问?目前的前端框架中,vue,react是使用人数比较多的两个,他们中间都定义了一些生命周期函数,Vue的created,mounted,react的componentDidMount,componentWillReceiveProps 等等我们在工作中经常使用这些函数,但是有时候似乎也需要去思考一下,这些函数具体是如何实现的钩子函数是什么钩子函数是一种隔离变化的手段,在父类中...
vue使用this.$set更新视图为什么只能更新一次
05-24
如果你使用 `this.$set` 方法更新了一个响应式属性,但是更新后并没有触发视图更新,可能是因为你没有在更新后进行 `this.$forceUpdate()`,或者你在更新后没有等待 Vue 的异步更新执行完毕。 不过一般情况下,如果...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
155
原创
29
点赞
185
收藏
27
粉丝
关注
私信
写文章

热门文章

  • 功率曲线k值_锂电池放电曲线全面解析 14518
  • python质数判断if isprime_使用Python判断质数(素数)的简单 7357
  • java清除控制台_Java:清除控制台 5523
  • html单击按钮时弹出输入框,点击按钮弹出模态框的一系列操作代码实例 3847
  • sql查询百分之20到百分之40的数据_拼多多面试题:如何查找前20%的数据? 3624

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • 服务器怎么导出数据库文件,怎么导出服务器数据库文件
  • 共享文件服务器迁移,服务器共享文件夹迁移
  • 江苏有线门户网站服务器地址,江苏有线手机客户端的登录服务器
2021年165篇
2020年217篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司濮阳seo优化报价济南百姓网标王推荐雅安网站优化按天扣费公司日照优秀网站设计报价金华网站制作海东网页制作哪家好松岗百度爱采购哪家好通辽关键词按天计费报价拉萨SEO按天收费价格南阳网站建设哪家好永新网站推广衢州外贸网站建设云浮网站排名优化哪家好济南模板制作多少钱扬州品牌网站设计价格巴中设计网站价格西安seo网站推广公司哈密网站设计模板哪家好盐田关键词排名公司深圳网站seo优化多少钱渭南关键词按天收费报价同乐建网站报价鹤壁百度竞价价格甘南SEO按天扣费报价漯河百度网站优化哪家好玉树高端网站设计多少钱南阳百度竞价哪家好马鞍山百搜标王多少钱霍邱网站搭建报价玉树百度爱采购公司歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化