精华内容
下载资源
问答
  • Vue响应式是从Vue的实例init()方法中开始的,在init()方法中先调用initState()初始化Vue实例的状态,在initState方法中调用了initData(), initData()是把data属性注入到Vue实例上,并且调用observe(data)将data...

    内容输出来源 拉勾教育大前端高薪训练营

    • Vue的响应式是从Vue的实例init()方法中开始的,在init()方法中先调用initState()初始化Vue实例的状态,在initState方法中调用了initData()initData()是把data属性注入到Vue实例上,并且调用observe(data)data对象转化成响应式的对象。

    • observe是响应式的入口, 在observe(value)中,首先判断传入的参数value是否是对象,如果不是对象直接返回。再判断value对象是否有__ob__这个属性,如果有说明做过了响应式处理,则直接返回,如果没有,创建observer对象,并且返回observer`对象。

    • 在创建observer对象时,给当前的value对象定义不可枚举的__ob__属性,记录当前的observer对象,然后再进行数组的响应式处理和对象的响应式处理,数组的响应式处理就是拦截数组的几个特殊的方法,pushpopshift等,然后找到数组对象中的__ob__对象中的dep,调用depnotify()方法,再遍历数组中每一个成员,对每个成员调用observer(),如果这个成员是对象的话,也会转换成响应式对象。对象的响应式处理,就是调用walk方法,walk方法就是遍历对象的每一个属性,对每个属性调用defineReactive方法

    • defineReactive会为每一个属性创建对应的dep对象,让dep去收集依赖,如果当前属性的值是对象,会调用observedefineReactive中最核心的方法是gettersettergetter 的作用是收集依赖,收集依赖时, 为每一个属性收集依赖,如果这个属性的值是对象,那也要为子对象收集依赖,最后返回属性的值。在setter 中,先保存新值,如果新值是对象,也要调用 observe ,把新设置的对象也转换成响应式的对象,然后派发更新(发送通知),调用dep.notify()

    • 收集依赖时,在watcher对象的get方法中调用pushTarget,记录Dep.target属性,访问data中的成员的时候收集依赖,defineReactivegetter中收集依赖,把属性对应的 watcher 对象添加到depsubs数组中,给childOb收集依赖,目的是子对象添加和删除成员时发送通知。

    • 在数据发生变化的时候,会调用dep.notify()发送通知,dep.notify()会调用watcher对象的update()方法,update()中的调用的queueWatcher()会去判断watcher是否被处理,如果这个watcher对象没有的话添加到queue队列中,并调用flushScheduleQueue()flushScheduleQueue()触发beforeUpdate钩子函数调用watcher.run()run()-->get() --> getter() --> updateComponent()

    • 然后清空上一次的依赖

    • 触发actived的钩子函数

    • 触发updated钩子函数

    在这里插入图片描述

    展开全文
  • 简述vue响应式原理

    2021-08-09 11:22:37
    响应式数据的最终目标,是当对象本身或对象属性发生变化时,将会运行一些函数,最常见的就是render函数。 在具体实现上,vue用到了几个核心部件: Observer Dep Watcher Scheduler Observer Observer要实现的目标...

    vue官方阐述:https://cn.vuejs.org/v2/guide/reactivity.html

    响应式数据的最终目标,是当对象本身或对象属性发生变化时,将会运行一些函数,最常见的就是render函数。

    在具体实现上,vue用到了几个核心部件

    1. Observer
    2. Dep
    3. Watcher
    4. Scheduler

    Observer

    Observer要实现的目标非常简单,就是把一个普通的对象转换为响应式的对象

    为了实现这一点,Observer把对象的每个属性通过Object.defineProperty转换为带有gettersetter的属性,这样一来,当访问或设置属性时,vue就有机会做一些别的事情。
    在这里插入图片描述

    Observer是vue内部的构造器,我们可以通过Vue提供的静态方法Vue.observable( object )间接的使用该功能。

    在组件生命周期中,这件事发生在beforeCreate之后,created之前。

    具体实现上,它会递归遍历对象的所有属性,以完成深度的属性转换。

    由于遍历时只能遍历到对象的当前属性,因此无法监测到将来动态增加或删除的属性,因此vue提供了$set$delete两个实例方法,让开发者通过这两个实例方法对已有响应式对象添加或删除属性。

    对于数组,vue会更改它的隐式原型,之所以这样做,是因为vue需要监听那些可能改变数组内容的方法
    在这里插入图片描述

    总之,Observer的目标,就是要让一个对象,它属性的读取、赋值,内部数组的变化都要能够被vue感知到。

    Dep

    这里有两个问题没解决,就是读取属性时要做什么事,而属性变化时要做什么事,这个问题需要依靠Dep来解决。

    Dep的含义是Dependency,表示依赖的意思。

    Vue会为响应式对象中的每个属性、对象本身、数组本身创建一个Dep实例,每个Dep实例都有能力做以下两件事:

    • 记录依赖:是谁在用我
    • 派发更新:我变了,我要通知那些用到我的人

    当读取响应式对象的某个属性时,它会进行依赖收集:有人用到了我

    当改变某个属性时,它会派发更新:那些用我的人听好了,我变了

    Watcher

    这里又出现一个问题,就是Dep如何知道是谁在用我?

    要解决这个问题,需要依靠另一个东西,就是Watcher。

    当某个函数执行的过程中,用到了响应式数据,响应式数据是无法知道是哪个函数在用自己的

    因此,vue通过一种巧妙的办法来解决这个问题

    我们不要直接执行函数,而是把函数交给一个叫做watcher的东西去执行,watcher是一个对象,每个这样的函数执行时都应该创建一个watcher,通过watcher去执行

    watcher会设置一个全局变量,让全局变量记录当前负责执行的watcher等于自己,然后再去执行函数,在函数的执行过程中,如果发生了依赖记录dep.depend(),那么Dep就会把这个全局变量记录下来,表示:有一个watcher用到了我这个属性

    当Dep进行派发更新时,它会通知之前记录的所有watcher:我变了

    每一个vue组件实例,都至少对应一个watcher,该watcher中记录了该组件的render函数。

    watcher首先会把render函数运行一次以收集依赖,于是那些在render中用到的响应式数据就会记录这个watcher。

    当数据变化时,dep就会通知该watcher,而watcher将重新运行render函数,从而让界面重新渲染同时重新记录当前的依赖。

    Scheduler

    现在还剩下最后一个问题,就是Dep通知watcher之后,如果watcher执行重运行对应的函数,就有可能导致函数频繁运行,从而导致效率低下

    试想,如果一个交给watcher的函数,它里面用到了属性a、b、c、d,那么a、b、c、d属性都会记录依赖,于是下面的代码将触发4次更新:

    state.a = "new data";
    state.b = "new data";
    state.c = "new data";
    state.d = "new data";
    

    这样显然是不合适的,因此,watcher收到派发更新的通知后,实际上不是立即执行对应函数,而是把自己交给一个叫调度器的东西

    调度器维护一个执行队列,该队列同一个watcher仅会存在一次,队列中的watcher不是立即执行,它会通过一个叫做nextTick的工具方法,把这些需要执行的watcher放入到事件循环的微队列中,nextTick的具体做法是通过Promise完成的

    nextTick 通过 this.$nextTick 暴露给开发者

    nextTick 的具体处理方式见:https://cn.vuejs.org/v2/guide/reactivity.html#%E5%BC%82%E6%AD%A5%E6%9B%B4%E6%96%B0%E9%98%9F%E5%88%97

    也就是说,当响应式数据变化时,render函数的执行是异步的,并且在微队列中

    总体流程

    image-20210226163936839

    展开全文
  • 简述Vue响应式原理

    2020-03-27 07:56:03
    data的属性被转换成getter和setter,并且记录相应的依赖。当它被改动时,会通知相应的依赖。 所有的组件实例都有相应的watcher实例,而watcher实例会依赖相应的setter。 当数据变化的时候,会调用setter,而setter会...
    1. data的属性被转换成getter和setter,并且记录相应的依赖。当它被改动时,会通知相应的依赖。
    2. 所有的组件实例都有相应的watcher实例,而watcher实例会依赖相应的setter。
    3. 当数据变化的时候,会调用setter,而setter会通知watcher实例,watcher会更新相应的视图

    图:

    • data 属性 - > { getter, setter }
    • 组件 -> watcher --------> ↑
    • setter -> watcher -> 更新视图
    展开全文
  • vm状态的初始化,整个响应式是从init方法中开始的,在init方法中,调用initState方法初始化状态,在initState方法中调用initData(),将data属性注入到vue实例上,并且调用observe()将其转化为响应式对象,...

    数据响应式是指,当数据发生变化自动更新视图,不需要手动操作dom,

    第一步、入口,initState()

    vm状态的初始化,整个响应式是从init方法中开始的,在init方法中,调用initState方法初始化状态,在initState方法中调用initData(),将data属性注入到vue实例上,并且调用observe()将其转化为响应式对象,observe是响应式的入口

    第二步、observe(value)

    位于src/core/observer/index.js,首先判断value是否是对象,如果不是对象直接返回,判断value对象是否有

    __ob__,如果有证明value已经做过响应化处理,是响应式数据,则直接返回,如果没有,则在第三步创建observer对象,并将其返回。

    第三步、Observe()

    位于src/core/observer/index.js,给value对象定义不可枚举的__ob__属性,记录当前的observer对象,进行数组的响应化处理,设置数组中的方法push、pop、sort等,这些方法会改变原数组,所以当这些方法被调用的时候,会发送通知,找到observe对象中的dep,调用dep.notify()方法,然后调用数组中的每一个成员,对其进行响应化处理,如果成员是对象,也会将转化为响应式对象,如果value是对象的话,会调用walk(),遍历对象中的每一个成员,调用defineReactive()

    第四步、defineReactive

    src/core/observer/index.js,为每一个属性创建dep对象,如果当前属性是对象,递归调用observe().

    getter:为每一个属性收集依赖,如果当前属性是对象,也为对象的每一个属性收集依赖,最终返回属性值。

    setter:保存新值,如果新值是对象,则调用observe,派发更新(发送通知),调用dep.notify()

    第五步、依赖收集

    在watcher对象的get方法中调用pushTarget,会把当前的watcher记录Dep.target属性,访问的data成员的时候收集依赖,访问值的时候会调用defineReactive的getter中收集依赖,把属性对应的watcher对象添加到dep的subs数组中,如果属性是对象,则给childOb收集依赖,目的是子对象添加和删除成员时发送通知。

    第六步、Watcher

    当数据发生变化时,会调用dep.notify(),调用watcher对象的update()方法,在update方法中会调用queueWatcher(),方法中会判断watcher是否被处理,如果没有,则将其添加到queue队列中,并调用flushSchedulerQueue()刷新任务队列,在flushSchedulerQueue中,会触发beforeUpdate钩子函数,然后调用watcher.run(),然后清空上一次的依赖,触发actived钩子函数,触发update钩子函数。

    展开全文
  • Vue响应式原理

    2019-12-16 17:38:21
    一、简介 Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会...Vue的数据双向绑定,响应式原理,其实就是通过Object.defineProperty()结合发布者...
  • Vue响应式原理之defineReactive defineReactive 不论如何,最终响应式数据都要通过defineReactive来实现,实际要借助ES5新增的Object.defineProperty。 defineReactive接受五个参数。obj是要添加响应式数据的对象;...
  • 什么是 Vue 响应式 ? 当视图模型(VM)中的数据模型(M)发生改变时, 视图(V)就会进行更新。 Vue 响应式怎么实现 ? 官网说明 : 当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历...
  • 浅谈Vue响应式原理

    千次阅读 2021-02-02 21:22:39
    二、响应式的基本原理 1.通过Object.definePropert来实现监听数据的改变和读取(属性中的getter和setter方法) 实现数据劫持 2.观察者模式(发布者-订阅者) 观察者(订阅者) – Watcher: update():当事件发生时,...
  • vue2响应式原理解析 data的响应 vue2中的简单而言就是object.defineProperty劫持get和set,对于数组直接赋值等操作不能实现响应式,对于data中新增的属性也不支持响应,必须用vue.$set设置。 vu
  • vue深入响应式原理是什么? v-model的原理? 深入响应式指的就是数据驱动 vue是通过数据劫持和事件的订阅发布模式来实现的,数据劫持指的是vue通过observer观察者对象对data选项中的属性做getter和setter设置,然后...
  • 开始重点倾向问源码 我相信最近去面试的人都会有这个体会,去年面试官只问我怎么用vue,今年开始问我vue响应式原理,以及vue各种相关库的源码? 结果回答得支支吾吾。毕竟大家忙着天天写业务代码,哪有空去研究源码...
  • 创建Vue3.Observer 实现响应式数据 1.简述功能 我们实现的一个带有响应式功能的简单Vue框架。 功能: 负责接收初始化的参数(options) 负责把data中的属性注入到Vue实例,转换成getter/setter 负责调用observer监听...
  • vue.js 响应式回顾 Proxy 对象实现属性监听 多层属性嵌套,在访问属性过程中处理下一层属性 默认监听动态添加的属性 默认监听属性的删除操作 默认监听数组的索引和 length 属性 可以作为单独的模块使用 核心方法...
  • 1. 实现响应式 响应基本类型变量 首先看一下响应式预期应该是什么样的,新建一个 demo.js 文件,内容如下: //这种写成一行完全是为了节省空间,实际上我会一行一个变量 leta=1,b=2,c=a*b console.log('c:'...
  • Vue 首次渲染的过程

    2021-11-13 17:20:30
    二,Vue 初始化过程 1,首先取出 Vue 的 $mount 进行重写,给 $mount 增加新的功能 // src/platform/web/entry-runtime-with-compiler.js // 保留 Vue实例的 $mount 方法 const mount = Vue.prototype.$mount ...
  • vue-响应式原理

    2021-02-15 16:27:15
    1.vue响应式原理核心使用的API是:Object.defineProperty(obj,key,val) 会对props和data、computed中的数组和对象都进行一个遍历,这个过程其实就是赋予数据set和get方法,让数据的访问和赋值有一些内部处理 2.由于...
  • vue响应式原理

    2018-12-04 00:51:16
    最近看了一篇文章讲的是vue响应式的实现原理,复述一下吧~ 文章参考:https://mp.weixin.qq.com/s/v8eT3WGolbabXDI24Ybx9Q 或许还没有原文说的清楚,可能有理解错的地方,欢迎大佬路过敲打~ 只是单纯按照原文打了一...
  • 这里的响应式指的是,当你的数据有变化,vue能够做出响应,然后去重新渲染页面,它采用数据劫持结合发布者---订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter getter,在数据变动时发布消息给...
  • 戳蓝字"前端优选"关注我们哦!前言介绍从本文开始,我们正式进入vue3.0 源码解析流程。个人觉得从ceateApp入手并不是最佳的学习方案,所以我们先从composi...
  • 简述vue响应式原理

    2020-03-17 20:29:12
    1.data的属性被转化为getter和setter并且被记录入相应的依赖, 再被改动的时候会通知响应的依赖。 2.所有的组件实例都会有它对应的watcher实例,而watcher实例会依赖于相应的setter。 3.当数据变化时setter会被...
  • Vue响应式原理简述

    2021-11-27 12:23:56
    Vue响应式原理简述依赖技术图解过程 依赖技术 问题:Vue如何监听data的改变? => 技术:Object.defineProperty函数。在其中的set方法中监听对象属性的改变。 问题:当data发生改变时,Vue如何知道要通知哪些...
  • 对于做vue响应式,问自己的内心的几个问题如下: 1)怎么做的数据劫持,vue2和 vue3的区别? 答: vue2的数据劫持是使用是es5的 Object.defineProperty的setter 和 getter方法来对对于数据的读取和设置的, 但是...
  • 浅析Vue3.0响应式原理

    2021-02-06 13:18:06
    刚好快要过年了,公司的事情不是很多,这才抽出时间来学习下vue3.0的响应式原理! 回顾Vue2.x 响应式原理 利用观察者模式 + Object.defineProperty ,收集依赖效率较低,对于深层次数据收集不友好 对于复杂类型数据...
  • Vue.js源码剖析-响应式原理,虚拟DOM,模板编译和组件化 一,简答题 1,请简述Vue首次渲染的过程。 Vue初始化,实例成员,静态成员 新的Vue()调用构造函数 构造函数中调用this._init()相当于整个Vue的入口 _...
  • 1.请简述 Vue 首次渲染的过程。 第一步、Vue初始化,实例成员、静态成员 首先进行vue的初始化,即初始化实例成员及静态成员. 第二步、new Vue() 初始化结束以后,调用vue的构造函数new Vue(),在构造函数中调用this....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,593
精华内容 637
关键字:

简述vue的响应式原理

vue 订阅