Vue深入讲解数据响应式原理

目录
  • 响应式是什么
  • 如何实现数据响应式
  • 实现对象属性拦截
  • 通用的劫持方案
  • 总结

响应式是什么

简而言之就是数据变页面变

如何实现数据响应式

在Javascript里实现数据响应式一般有俩种方案,分别对应着vue2.x 和 vue3.x使用的方式,他们分别是:

对象属性拦截 (vue2.x)

Object.defineProperty

对象整体代理 (vue3.x)

Proxy

其中对象属性拦截,道理都是相通的

实现对象属性拦截

字面量对象定义

let data = {
    name:'小兰同学'
}

Object.defineProperty对象定义

let data = {}
Object.defineProperty(data,'name',{
    // 访问name属性就会执行此方法 返回值就是获取到的值
    get(){
       console.log('name属性被获取了')
       return '小兰同学'
    },
    // 设置新值就会执行此方法 newVal就是设置的新值
    set(newVal){
       console.log('name属性被设置新值了')
       console.log(newVal)
    }
})

我们可以通过 data.name 去获取值,也可以通过 data.name=‘小赵同学’去赋值

存在问题演示

最后获取name值没有被改变

解决方案

我们可以 通过一个中间变量 _name 来中转get函数和set函数之间的联动

let data = {}
let _name = '小兰同学'
Object.defineProperty(data,'name',{
    // 访问name属性就会执行此方法 返回值就是获取到的值
    get(){
       console.log('name属性被获取了')
       return _name
    },
    // 设置新值就会执行此方法 newVal就是设置的新值
    set(newVal){
       console.log('name属性被设置新值了')
       console.log(newVal)
       _name = newVal
    }
})

结果验证

通用的劫持方案

大家想想看,如果现在有一份已经声明好了数据的对象,我们如何通过劫持的方法把每一个属性都变成setter和getter的形式

下面是一份已经声明好的数据

let data = {
    name: '小兰同学',
    age: 18,
    height:180
}

我们想让里面所有的属性都变成响应式的,并且get和set方法中对于每个属性值的操作是连通的

let data = {
    name: '小兰同学',
    age: 18,
    height:180
}
// 遍历每一个属性
Object.keys(data).forEach((key)=>{
    // key 属性名
    // data[key] 属性值
    defineReactive(data,key,data[key])
})
// 响应式转化方法
function defineReactive(data,key,value){
    Object.defineProperty(data,key,{
        get(){
           return value
        },
        set(newVal){
          value = newVal
        }
    })
}

结构说明:这个地方实际上使用了闭包的特性,看下图,在每一次的defineReactive函数执行的时候,都会形成一块独立的函数作用域,传入的value 因为闭包的关系会常驻内存,这样一来,每个defineReactive函数中的value 会作为各自set和get函数操作的局部变量

总结

  • 所谓的响应式其实就是拦截对象属性的访问和设置,插入一些我们自己想要做的事情
  • 在Javascript中能实现响应式拦截的方法有俩种,Object.defineProperty方法和Proxy对象代理
  • 回归到vue2.x中的data配置项,只要放到了data里的数据,不管层级多深不管你最终会不会用到这个数据都会进行递归响应式处理,所以要求我们如非必要,尽量不要添加太多的冗余数据在data中
  • 需要了解vue3.x中,解决了2中对于数据响应式处理的无端性能消耗,使用的手段是Proxy劫持对象整体 + 惰性处理(用到了才进行响应式转换)

到此这篇关于Vue深入讲解数据响应式原理的文章就介绍到这了,更多相关Vue数据响应式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue 数据响应式相关总结

    在说数据响应式之前,我们要解决一个很重要的问题,那就是Vue到底对data做了什么?先从getter和setter说起,我们用那个他们来对虚拟的属性进行读写. getter和setter 有如下代码 let obj0 = { 姓: "高", 名: "圆圆", age: 18 }; // 需求一,得到姓名 let obj1 = { 姓: "高", 名: "圆圆", 姓名() { return this.姓 + this.名; }

  • vue数据响应式原理知识点总结

    vue2.0数据响应式原理 对象 Obect.defineproperty 定义对象的属性mjm defineproperty 其实不是核心的为一个对象做数据双向绑定,而是去给对象做属性标签,设置一系列操作权限,只不过属性里的get和set实现了响应式 var ob = { a: 1, b: 2 } //1-对象 2-属性 3-对于属性的一系列配置 Object.defineProperty(ob, 'a' , { //a对象则是ob的绝对私有属性,,默认都是true writable: fal

  • 浅谈Vue 数据响应式原理

    前言 Vue的数据响应主要是依赖了Object.defineProperty(),那么整个过程是怎么样的呢?以我们自己的想法来走Vue的道路,其实也就是以Vue的原理为终点,我们来逆推一下实现过程. 本文代码皆为低配版本,很多地方都不严谨,比如 if(typeof obj === 'object')这是在判断obj是否为为一个对象,虽然obj也有可能是数组等其他类型的数据,但是本文为了简便,就直接这样写来表示判断对象,对于数组使用Array.isArray(). 改造数据 我们先来尝试写一个函数

  • 深入理解Vue的数据响应式

    1. ES语法的getter和setter 在开始了解 Vue 的数据响应式原理前应该先搞清楚 ES语法 中的 getter 和 setter 方法的具体用法. getter和setter 方法是以 get 和 set 关键字来为对象添加虚拟属性的一种方式.这种属性其实并不真实存在,而是以取值函数 getter 和存值函数 setter 来模拟的一种属性.目的是对某个属性设置存值函数和取值函数,拦截该属性的存取行为,以便于对该属性的存取做一些限定处理.如下所示(以下代码来源于 mdn) gett

  • 详解vue数据响应式原理之数组

    目录 src/core/observer/index.js src/core/observer/array.js arrayMethods 总结 src/core/observer/index.js src/core/observer/array.js arrayMethods 当data的数组对象中本来没有某个属性,然后点击按钮动态增加某个属性的时候,此时此属性是没有get和set的,也就是没有响应式机制,如果想要让你动态增加的某个属性有响应式变化,那么就直接在数据的源头给他初始化这个属性,具

  • 详解实现vue的数据响应式原理

    这篇文章主要是给不了解或者没接触过 vue 响应式源码的小伙伴们看的,其主要目的在于能对 vue 的响应式原理有个基本的认识和了解,如果在面试中被问到此类问题,能够知道面试官想让你回答的是什么?「PS:文中如有不对的地方,欢迎小伙伴们指正」 响应式的理解 响应式顾名思义就是数据变化,会引起视图的更新.这篇文章主要分析 vue2.0 中对象和数组响应式原理的实现,依赖收集和视图更新我们留在下一篇文章分析. 在 vue 中,我们所说的响应式数据,一般指的是数组类型和对象类型的数据.vue 内部通过

  • Vue data的数据响应式到底是如何实现的

    研究过程 一般形式 data:{ n:0 } :以这样的方式存储数据,vue能够监听其变化吗?显然是不能的. 使用Obj.defineProperty let data1 = {} Object.defineProperty(data1, 'n', { value: 0 }) 为什么要使用defineProperty呢?这不是把一般形式复杂化了吗? 引出主角getter setter. 如果我们想对数据监听进行处理呢?(假设修改的数据必须>=0) let data2 = {} data2._n

  • Vue深入讲解数据响应式原理

    目录 响应式是什么 如何实现数据响应式 实现对象属性拦截 通用的劫持方案 总结 响应式是什么 简而言之就是数据变页面变 如何实现数据响应式 在Javascript里实现数据响应式一般有俩种方案,分别对应着vue2.x 和 vue3.x使用的方式,他们分别是: 对象属性拦截 (vue2.x) Object.defineProperty 对象整体代理 (vue3.x) Proxy 其中对象属性拦截,道理都是相通的 实现对象属性拦截 字面量对象定义 let data = { name:'小兰同学' }

  • vue.js数据响应式原理解析

    目录 Object.defineProperty() 定义 defineReactive 函数 递归侦测对象的全部属性 流程分析 observe 函数 Observer 类 完善 defineReactive 函数 One More Thing Object.defineProperty() 得力于 Object.defineProperty() 的特性,vue 的数据变化有别于 react 和小程序,是非侵入式的.详细介绍可以看 MDN 文档,这里特别说明几点: get / set 属性是函数

  • Vue双向数据绑定与响应式原理深入探究

    目录 一.双向数据绑定和数据响应式是相同的吗 二.双向数据绑定的原理 三.数据响应式的原理与实现 一.双向数据绑定和数据响应式是相同的吗 不相同,原因如下: 响应式是指通过数据区驱动DOM视图的变化,是单向的过程. 双向数据绑定就是无论用户更新View还是Model,另一个都能跟着自动更新. 例如:当用户填写表单时,View的状态就被更新了,如果此时可以自动更新Model的状态,那就相当于我们把Model和View做了双向绑定. 双向数据绑定的数据和DOM是一个双向的关系. 响应式是双向绑定的一

  • Vue3.0数据响应式原理详解

    基于Vue3.0发布在GitHub上的第一版源码(2019.10.05)整理 预备知识 ES6 Proxy,整个响应式系统的基础. 新的composition-API的基本使用,目前还没有中文文档,可以先通过这个仓库(composition-api-rfc)了解,里面也有对应的在线文档. 先把Vue3.0跑起来 先把vue-next仓库的代码clone下来,安装依赖然后构建一下,vue的package下的dist目录下找到构建的脚本,引入脚本即可. 下面一个简单计数器的DEMO: <!DOCTY

  • 稍微学一下Vue的数据响应式(Vue2及Vue3区别)

    什么是数据响应式 从一开始使用 Vue 时,对于之前的 jq 开发而言,一个很大的区别就是基本不用手动操作 dom,data 中声明的数据状态改变后会自动重新渲染相关的 dom. 换句话说就是 Vue 自己知道哪个数据状态发生了变化及哪里有用到这个数据需要随之修改. 因此实现数据响应式有两个重点问题: 如何知道数据发生了变化? 如何知道数据变化后哪里需要修改? 对于第一个问题,如何知道数据发生了变化,Vue3 之前使用了 ES5 的一个 API Object.defineProperty Vue

随机推荐