IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue的响应式原理 -> 正文阅读

[JavaScript知识库]vue的响应式原理

之所以成为响应式,是因为vue可以监测到数据的变化,之后进行重新渲染。我们把这个过程叫做变化侦测。

首先聊聊变化侦测,分为两种类型推和拉。在react框架中使用的是拉的形式,当数据发生变化是,是不知道具体哪个状态变化了,需要暴力对比DOM节点,来找到需要重新渲染的节点。而Vue的变化侦测属于推的形式,当数据发生变化的时候,可以知道有数据发生了改变,而且可以知道那些数据发生了改变。但是推的形式追踪变化侦测,需要在每一个具体的DOM节点上添加依赖,会导致内存的消耗较大。所以vue从2.0开始,引入了虚拟DOM,不再是每一个具体的DOM结点有一个依赖,而是每个组件添加一个依赖,当数据变化的时候,定位到哪个组件发生了变化,之后在组件内进行虚拟DOM的对比。

我们再来看聊聊如何追踪变化,其实vue对于Object(对象类型)和Array(数组类型)的变化侦测的方式有一点不太一样。先说对于Object的侦测

Object的变化侦测

1.原理

vue2.0使用的侦测方法是Object.defineProperty()

Object可以通过Object.defineProperty将各个属性转换成getter/setter的形式来追踪,读取数据是触发getter,修改数据的时候触发setter。我们在getter中收集依赖,当setter被触发的时候,就去通知getter里面的依赖。依赖接受到通知后,会触发视图更新或回调函数等。

是不是理解起来有一点懵懂,没事我们细剖一下。

1.收集依赖?什么是依赖呢?是watcher!它相当于一个中介的角色,当数据发生变化时通知它,然后它再通知其他的地方。

? ? ? ? watcher的原理:watcher会把自己设置到全局唯一的一个指定位置处,然后读取数据,读取数据就会触发getter,getter就会从这个全局唯一的一个指定未知的地方读取到正在读取的watcher,并把它收集起来,当这个数据发生变化的时候,就可以去通知他数据变化了!

注意:getter/setter只能追踪一个数据是否被修改,无法追踪新增的属性或者删除的属性,需要用this.$set()或者this.$delete()

?Array的变化侦测

侦测的原理但是一样的,只不过侦测的方式有不同。

我们在改变数组数据时,通常使用数组的一些方法,如push,shift,splice等方法。我们只要能在调用push等操作的时候通知发生了改变就可以了。如果使用Object的getter和setter的形式就不可以了。但是JS并没有提供可以拦截原型方法的能力。所以用自定义方法覆盖原生的原型方法来解决。即拦截器。所以Array是在getter中收集依赖,在拦截器中触发依赖。

1.拦截器:拦截器就是一个和Array.prototype一样的一个对象,里面包含的属性一摸一样

2.拦截器如何覆盖Array的原型:在覆盖Array原型时,不可以直接覆盖,会污染到全局的Array。只需要拦截器覆盖那些响应式数组的原型就ok!?数据如果想转化成响应式那么一定会通过Observer,所以只需要在Observer中使用拦截器覆盖即可。

拦截器的源码:

export const arrMethods = Object.create(Array.prototye); // 继承Array.prototype
['push','pop','shift','unshift','splice','sort','reverse'].forEach((methods) =>{
    const original = arrayProto[method]
    Object.defineProperty(arrarMethods,method, {
        value: function mutator(..args) {
            return original.apply(this, args)
        },
        enumerable:false
        writable:true
        configurable:true
    }
}

当使用push方法的时候,调用的就是arrayMethods.push,即为mutator函数。

注意:对于Array的变化侦测是通过拦截原型的方式实现的,所以对于一些数组操作,vue时检测不到的,比如arr[1]=2,arr.length = 0.

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-25 23:09:09  更:2022-09-25 23:10:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:12:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码