目录

  • [1]什么叫双向数据绑定?
  • [2]双向绑定原理
    • vue2.x实现双向绑定
      • Object.defineProperty对象(es6新增)
        • 语法
        • 举例说明
        • 踩坑 - 给某属性进行双向绑定
        • 踩坑 - 给对象的所有属性进行双向绑定
    • vue2.x实现双向绑定
    • vue2.x实现双向绑定缺点
  • vue3.x实现双向绑定
    • Proxy构造函数(es6新增)
    • Reflect对象
  • vue3.x双向绑定

[1]什么叫双向数据绑定?

  • 视图中的数据发生了变化,data中的数据也要对应改变;
  • data中的数据发生了变化,视图上的数据也要对应改变;

[2]双向绑定原理

vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;

vue2.x实现双向绑定

在vue2.x中数据双向绑定的核心是使用 Object.defineProperty(对象,key,{get(),set()})方法来给对象的属性添加getset方法实现的!

Object.defineProperty对象(es6新增)
语法
Object.defineProperty(obj,key,{enumerable:false , // 控制属性是否可以枚举,默认值为falsewritable:false, // 控制属性是否可以被修改,默认值为falseconfigurable:false, // 控制属性是否可以被删除,默认值为false// 当获取该属性时就会调用get方法 ,返回值为获取到的值get(){return xxx}// 当给该属性进行赋值时就会调用set方法set(val){}
})
举例说明

需求:现在有如下代码,希望person对象存在一个age属性,属性值为number变量的值且 number值与age属性值能够实时双向绑定

let number = 18
let person = {name:'chaochao',sex:'女'
}

实现:

let number = 20
let person = {name:'chaochao',sex:'女'
}
Object.defineProperty(person,'age',{get(){console.log('@@@获取age')return number},set(val){console.log('@@@修改age')number = val}
})

结果:

踩坑 - 给某属性进行双向绑定

在此示例中给data对象的name属性通过defineProperty进行 读取/赋值;

let data = {name: 'chaochao'
}
Object.defineProperty(data, 'name', {get () {// [2] 若是在返回时直接通过点语法获取会再次调用get方法 -> 递归却没有递归边界---死循环return data.name},set (value) {data.name = value}
})
// [1]在此处获取了data的name属性值,就会调用name属性的get方法
data.name

改正:

let data = {name: 'chaochao'
}
let _name = data.name
Object.defineProperty(data, 'name', {get () {return _name},set (value) {data.name = value}
})
// [1]在此处获取了data的name属性值,就会调用name属性的get方法
data.name
踩坑 - 给对象的所有属性进行双向绑定
  let data = {name: 'chaochao',sex:'女',say:''
}
let _name = data.name
for(let key in data){Object.defineProperty(data, key, {get () {return data[key] // 无限调用},set (str) {data[key] = str // error: Maximum call stack size exceeded}
})
}

改正:

let data = {name:'chaochao',sex:'女',say:''
}
let _name = data.name
Object.keys(data).forEach((key) => {defineProperty(data, key, data[key])
})
function defineProperty(obj,key,val) {Object.defineProperty(obj, key, {get () {console.log('@@@get', val)return val},set (str) {console.log('@@@set', val,str)val = str}
})
}

vue2.x实现双向绑定

在通过new关键字实例化对象时,传入的配置项中添加了 data属性

const vm = new Vue({el:'#app',data:{name:'chaochao',sex:'女',say:'hello word'}})

vue会将data存在在实例化对象的_data属性中;

const data = {name:'chaochao',sex:'女',say:'hello word'
}
const vm = new Vue({el:'#app',data
})
console.log(data==vm._data) // true

将data中的数据平铺在vue实例化对象身上

使用Object.defineProperty实现数据代理。
模拟数据代理过程

// 模拟配置项data
const data = {name:'chaochao',sex:'女',say:'hello word'
}// 模拟vue实例化对象 代码中更新的是_data中的数据,视图上更改的是vue实例化对象身上的数据
const vm ={_data:data, // 存储数据...data // 数据劫持-> 更新试图
}
for(let key in vm._data){Object.defineProperty(vm._data, key , {//  当获取属性值时返回vue实例化对象身上的对应的属性的属性值get(){return vm[key]},// 当修改属性值时-> 将vue实例化对象身上对应的属性值一起修改set(val){vm[key] = val}})
}

vue2.x实现双向绑定缺点

  • 对象:只能给对象中已经存在的属性进行双向绑定!

    • 新增属性、删除属性,视图不会更新
  • 数组:直接通过下标修改数组,视图不会更新

所以在vue2.x中有时会出现双向绑定失败(实例化对象中的数据改变了,但是视图上并没有重新渲染)的现象-可以使用 $set 解决

vue3.x实现双向绑定

在vue2.x中数据双向绑定的核心是使用new Proxy(对象,{get(),set()})方法来给对象的属性添加getset方法实现的!

Proxy构造函数(es6新增)

语法

let data = {name:'chaochao',sex:'女',say:''
}
//data为源数据 p为代理数据
const p = new Proxy(data,{// 拦截读取属性值  ->  当读取p身上的属性时就会触发该方法,该函数return的值就是读取到的值// target:源数据; prop:key值get (target, prop) {console.log('@@@读取数据了')return target[prop] // 默认返回的是源数据的值},// 拦截设置属性值或添加新属性 -> 当修改p身上的属性的属性值或给p添加新属性时就会触发该方法set (target, prop, value) {console.log('@@@修改数据')target[prop] = value // 当修改了代理数据就去修改源数据的值},// 拦截删除属性 -> 当删除p身上的属性时就会触发该方法deleteProperty (target, prop) {console.log('@@@删除数据 ')return delete[prop] // 当删除了代理数据的属性就删除源数据的属性并返回是否删除成功}
})

Reflect对象

我们可以通过Reflect对象去增删改查对象中的属性
语法

let data = {name:'chaochao',sex:'女',say:''
}
// 新增属性
console.log(Reflect.set(data,'age', 18)) // true
// 获取属性
console.log(Reflect.get(data,'name'), Reflect.get(data,'age')) // chaochao, 18
// 修改属性
console.log(Reflect.set(data,'name','niuniu')) // true
// 删除属性
console.log(Reflect.deleteProperty(data,'sex')) // true
// 查看对象
console.log(data) // {name: 'niuniu', say: '', age: 18}

优点是容错性强!

vue3.x双向绑定

 new Proxy(data,{get (target, prop) {return Reflect.get(target,prop)},set (target, prop, value) {Reflect.set(target,prop,value)},deleteProperty (target, prop) {return Reflect.deleteProperty(target, prop)}
})
  • 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
  • 通过Reflect(反射): 对源对象的属性进行操作。

Vue笔记_01双向数据绑定原理相关推荐

  1. vue中实现双向数据绑定原理,使用了Object.defineproperty()方法,方法简单

    在vue中双向数据绑定原理,我们一般都是用v-model来实现的 ,但一般在面试话会问到其实现的原理, 方法比较简单,就是利用了es5中的一个方法.Object.defineproperty(),它有 ...

  2. vue的v-model双向数据绑定原理

    双向数据绑定(v-model) v-model就是vue的双向绑定指令,能将页面上空间输入的值同步更新到相关绑定的属性,也会在更新data绑定属性的时候,更新页面上输入控件的值 v-model的原理: ...

  3. vue双向数据绑定原理分析--Mr.Ember

    vue双向数据绑定原理分析 摘要 vue常用,但原理常常不理解,下面我们来具体分析下vue的双向数据绑定原理. (1)创建一个vue对象,实现一个数据监听器observer,对所有数据对象属性进行监听 ...

  4. 【Vue的双向数据绑定原理】

    Vue的双向数据绑定原理 先说面试答案: 1. 什么是setter.getter 2. 什么是Object.defineProperty() ? 先简单的实现一个js的双向数据绑定来熟悉一下`Obje ...

  5. 前端面试题 HTML5 CSS3(盒子模型、盒子水平垂直居中、经典布局) JS(闭包、深浅克隆、数据劫持和拦截) 算法(排序、去重、数组扁平化) Vue(双向数据绑定原理、通信方式)

    前端面试题 HTML5 相关面试题 CSS3 相关面试题 盒子模型 盒子水平垂直居中的方案 经典布局方案 圣杯布局 双飞翼布局 flex布局 定位方式布局 css实现三角形 JS 相关面试题 8种数据 ...

  6. vue双向数据绑定原理 1

    1. 原理 1.1 vue双向数据绑定原理,又称vue响应式原理,是vue的核心,双向数据绑定是通过数据劫持结合发布订阅模式的方式来实现的,也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化 ...

  7. Vue 双向数据绑定原理

    原理 1.vue双向数据绑定原理,又称vue响应式原理,是vue的核心,双向数据绑定是通过数据劫持结合发布者订阅者模式的方式来实现的,通过Object.defineProperty()来劫持各个属性的 ...

  8. Vue 的双向数据绑定原理解析

    在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理.本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫myVue吧.结合注释,希望 ...

  9. Vue数据响应式与双向数据绑定原理区分

    很多小伙伴搞不清楚数据响应式与双向数据绑定这两个原理,还有人自然的认为它们两者是相同的,接下来我们来看看它们二者的区分吧! 数据响应式是Vue的核心特性之一,而双向数据绑定是通过指令或修饰符实现的一种 ...

最新文章

  1. python中的__new__概念(工厂
  2. 微软即将修复Windows 2000漏洞
  3. 怎么格式化电脑_U盘格式化后数据能恢复吗?人人都能学会的恢复方法!
  4. 深度学习图像融合_基于深度学习的图像超分辨率最新进展与趋势【附PDF】
  5. C++中多态的基本概念以及虚表的基本概念
  6. 计算机硬件知识考证题,2017年计算机硬件知识考试题及答案
  7. 【抄】更改eclipse配置
  8. Binary XML file line #27: Error inflating class Listview
  9. 小规模团队如何“微服务”管理
  10. 视图状态机制下的IStateManager接口
  11. PDF查看器之pdfvuer
  12. 任务栏的图标变成白色
  13. Ansible Inventory详细使用介绍
  14. XXL-Job启动源码详解
  15. 小丸子学Hadoop系列之——部署Hbase集群
  16. 阿里大鱼短信发送接口开发
  17. R语言|散点图 ———R语言数据可视化系列(一)
  18. JMeter 系列 —— BeanShell 取样器
  19. 同为科技(TOWE)8路RS485通讯智能机柜PDU时序电源管理器
  20. 论文投稿指南——中文核心期刊推荐(水利工程)

热门文章

  1. CURSOR 的用法
  2. java实现简单的电竞房间预定
  3. SAP GUI Dracula Theme 主题
  4. T045基于51单片机温湿度检测系统无线蓝牙传输Proteus仿真原理图PCB
  5. 我的第一个Chrome小插件-基于vue开发的flexbox布局CSS拷贝工具
  6. 虚幻4: 蓝图入门与进阶
  7. linux下deb包如何安装
  8. linux中文件层级系统
  9. 颜色帮你缓解职场压力 给你的心情换个色
  10. WebLogic 10.3.6.0 部署安装问题(简装版)