浅谈Vue响应式(数组变异方法)

这篇文章主要介绍了关于浅谈vue响应式(数组变异方法),有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

前言

很多初使用Vue的同学会发现,在改变数组的值的时候,值确实是改变了,但是视图却无动于衷,果然是因为数组太高冷了吗?

查看官方文档才发现,不是女神太高冷,而是你没用对方法。

浅谈Vue响应式(数组变异方法)

浅谈Vue响应式(数组变异方法)

看来想让女神自己动,关键得用对方法。虽然在官方文档中已经给出了方法,但是在下实在好奇的紧,想要解锁更多姿势的话,那就必须先要深入女神的心,于是乎才有了去探索Vue响应式原理的想法。(如果你愿意一层一层地剥开我的心。你会发现,你会讶异…… 沉迷于鬼哭狼嚎 无法自拔QAQ)。

立即学习“前端免费学习笔记(深入)”;

前排提示,Vue的响应式原理主要是使用了ES5的Object.defineProperty,毫不知情的同学可以查看相关资料。

为啥数组不响应?

仔细一想,Vue的响应是基于Object.definePropery的,这个方法主要是对对象属性的描述进行修改。数组其实也是对象,通过定义数组的属性应该也能产生响应的效果呀。先验证一下自己的想法,撸起袖子就开干。

const arr = [1,2,3];let val = arr[0];Object.defineProperty(arr,'0',{  enumerable: true,  configurable: true,  get(){    doSomething();    return val;  },  set(a){    val = a;    doSomething();  }});function doSomething() {}

登录后复制

然后在控制台中分别输入arr、arr[0] = 2、arr,可以看到如下图的结果。

浅谈Vue响应式(数组变异方法)

咦,一切居然都如预想猜想的一样。

接下来,看到这段代码,有的同学可能会有所疑问,为啥在get()方法里不直接返回this[0]呢?而是要借助val来返回值呢?仔细一想,卧槽!!!差点特么的死循环了,你想呀,get()本身就是获取当前属性的值,在get()里调用this[0]不是等同于再次调用了get()方法吗? 好可怕好可怕,简直吓死劳资了。

虽然你想象中的女神可能会这种姿势,但是你眼前的这个女神确实不是这种姿势的,像我这种屌丝属性暴露无疑的人怎么可能猜透女神的心思?为什么不这样响应数据呢?或许是因为数组和对象还是有所差别,定义数组的属性可能会产生一些麻烦与Bug。又或许是因为在交互的过程中可能会产生大量的数据,导致整体的性能下降。也有可能是作者权衡利弊之后用其他方法也可以达到数据响应的效果。反正我是猜不透啦。

为啥调用数组原生方法就可以响应了?

为什么使用了这些数组的方法就就能让数据响应了呢?先看看数组部分的源码吧。

简单的来讲,def的作用就是重新定义对象属性的value值。

//array.jsimport { def } from '../util/index'const arrayProto = Array.prototypeexport const arrayMethods = Object.create(arrayProto)//arrayMethods是对数组的原型对象的拷贝,//在之后会将该对象里的特定方法进行变异后替换正常的数组原型对象/** * Intercept mutating methods and emit events */[ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) { // cache original method //将上面的方法保存到original中 const original = arrayProto[method] def(arrayMethods, method, function mutator (...args) {  const result = original.apply(this, args)  const ob = this.__ob__  let inserted  switch (method) {   case 'push':   case 'unshift':    inserted = args    break   case 'splice':    inserted = args.slice(2)    break  }  if (inserted) ob.observeArray(inserted)  // notify change  ob.dep.notify()  return result })})

登录后复制

贴出def部分的代码

/** * Define a property. */export function def (obj: Object, key: string, val: any, enumerable?: boolean) { Object.defineProperty(obj, key, {  value: val,  enumerable: !!enumerable,  writable: true,  configurable: true })}

登录后复制

array.js是对数组的一些方法进行变异,我们以push方法来举个例子。首先 就是要用original = arrayProto[‘push’]来保存原生的push方法。

然后就是要定义变异的方法了,对于def函数,如果不深究的话,def(arrayMethods,method,function(){}),这个函数可以粗略的表示为arrayMethods[method] = function mutator(){};

假设在之后调用push方法,实际上调用的是mutator方法,在mutator方法中,第一件事就是调用保存了原生push方法的original,先求出实际的值。一堆文字看起来实在很抽象,那么写一段低配版的代码来表达源码的含义。

const push = Array.prototype.push;Array.prototype.push = function mutator (...arg){  const result = push.apply(this,arg);  doSomething();  return result}function doSomething(){  console.log('do something');}const arr = [];arr.push(1);arr.push(2);arr.push(3);

登录后复制

在控制台中查看结果为:。

浅谈Vue响应式(数组变异方法)

那么源码中的

const ob = this.__ob__  let inserted  switch (method) {   case 'push':   case 'unshift':    inserted = args    break   case 'splice':    inserted = args.slice(2)    break  }  if (inserted) ob.observeArray(inserted)  // notify change  ob.dep.notify()

登录后复制

这段代码就是对应的doSomething()了

在该代码中,清清楚楚的写了2个单词的注释notify change,不认识这2个单词的同学就百度一下嘛,这里就由我代劳了,这俩单词的意思是发布改变!每次调用了该方法,都会求出值,然后做一些其他的事情,比如发布改变与观察新增的元素,响应的其他过程在本篇就不讨论了。

[ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']

登录后复制

目前一共有这么些方法,只要用对方法就能改变女神的姿势哟!

小结

对于标题,我一改再改,一开始叫浅析Vue响应原理,但是后来一看 这个标题实在太大,那就从最简单的入手吧,先从数组入手,而且本篇也不会花费太多时间去阅读。如果本篇有什么地方写得有误,误导了他人,请一定指出,万分感激。

相关推荐:

浅谈Vue 数据响应式原理

以上就是浅谈Vue响应式(数组变异方法)的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2764134.html

(0)
上一篇 2025年3月8日 10:24:13
下一篇 2025年2月23日 12:25:05

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • JS随机生成数与序列方法详解

    这次给大家带来JS随机生成数与序列方法详解,JS随机生成数与序列的注意事项有哪些,下面就是实战案例,一起来看一下。 •1.Math.random(); 结果为0-1间的一个随机数(包括0,不包括1) •2.Math.floor(num); …

    编程技术 2025年3月8日
    200
  • 动态加载JS文件方法总结

    这次给大家带来动态加载JS文件方法总结,动态加载JS文件的注意事项有哪些,下面就是实战案例,一起来看一下。 一、使用document.write/writeln()方式 该种方式可以实现js文件的动态加载,原理就是在重写文档流,这种方式会导…

    编程技术 2025年3月8日
    200
  • 怎样传递数组参数至后台

    这次给大家带来怎样传递数组参数至后台,传递数组参数至后台的注意事项有哪些,下面就是实战案例,一起来看一下。 传递参数传递字符串,所以要把数组转换为字符串, var arr=[1,23,34,5];var str = arr.toString…

    编程技术 2025年3月8日
    200
  • Vue数据监听watch方法使用详解

    这次给大家带来Vue数据监听watch方法使用详解,Vue数据监听watch方法的注意事项有哪些,下面就是实战案例,一起来看一下。 watch本身很容易理解, watch负责将视图中的数据与某个函数关联起来 当Vue视图中的数据变化时, 关…

    2025年3月8日
    200
  • Vue操作自定义动态组件方法详解

    这次给大家带来Vue操作自定义动态组件方法详解,Vue操作自定义动态组件的注意事项有哪些,下面就是实战案例,一起来看一下。 现在基于vue的UI组件库有很多,比如iview,element-ui等。但有时候这些组件库满足不了我们的开发需求,…

    2025年3月8日 编程技术
    200
  • Vue项目里跨域处理方法

    这次给大家带来Vue项目里跨域处理方法,Vue项目里跨域处理的注意事项有哪些,下面就是实战案例,一起来看一下。 问题描述 前端 vue 框架,后台 php,百度跨域问题后台加这段代码 header(“Access-Control-Allow…

    2025年3月8日
    200
  • JS遍历不规则多维数组方法总结

    这次给大家带来JS遍历不规则多维数组方法总结,JS遍历不规则多维数组的注意事项有哪些,下面就是实战案例,一起来看一下。 直接进入正文: 我们有时候处理数据,可能会遇到一些不规则(无法预料的数据结构),那么拿到这种数据我们如何进行遍历操作呢?…

    2025年3月8日
    200
  • 去除vue中代码规范检测方法总结

    这次给大家带来去除vue中代码规范检测方法总结,去除vue中代码规范检测的注意事项有哪些,下面就是实战案例,一起来看一下。 我们在使用vue 脚手架时,为了规范团队的代码格式,会有一个代码规范检测,如果不符合规范就会报错,有时候我们不想按照…

    编程技术 2025年3月8日
    200
  • Vue实现双向绑定方法总结

    这次给大家带来Vue实现双向绑定方法总结,Vue实现双向绑定的注意事项有哪些,下面就是实战案例,一起来看一下。 1. v-model 指令 上例不过是一个语法糖,展开来是: text = e.target.value”/> 登录后复制…

    2025年3月8日
    200
  • JS刷新页面方法总结

    这次给大家带来JS刷新页面方法总结,JS刷新页面的注意事项有哪些,下面就是实战案例,一起来看一下。 JS刷新当前页面的几种方法总结 reload 方法,该方法强迫浏览器刷新当前页面 replace 方法,该方法通过指定URL替换当前缓存在历…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论