理解

vue是一个非常优秀的框架,其优秀的双向绑定原理,mvvm模型,组件,路由解析器等,非常的灵活方便,也使开发者能够着重于数据处理,让开发者更清晰的设计自己的业务。

双向绑定,就是数据变化的时候,自动触发视图的变化。

实践

我们都理解,vue2.0中,双向绑定的核心为Object.defineProperty(obj, prop, descriptor),方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象

参数obj要在其上定义属性的对象。

参数prop要定义或修改的属性的名称。

参数descriptor将被定义或修改的属性描述符。

返回被传递给函数的对象。

尝试Object.defineProperty拦截用户对变量的设置

我们可以新建一个项目,用来模拟及学习vue双向绑定的相关内容

  1. + vue相关
  2. + |- 双向绑定原理
  3. + |- js
  4. + |- myVue.js
  5. + |- index.html

修改index.html中的内容,引入自己创建的myVue.js。

  1. + <!DOCTYPE html>
  2. + <html lang="en">
  3. + <head>
  4. + <meta charset="UTF-8">
  5. + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. + <title>Document</title>
  7. + </head>
  8. + <body>
  9. +
  10. + <script src="./js/myVue.js"></script>
  11. + </body>
  12. + </html>

编辑myVue.js的内容,来尝试一下Object.defineProperty(obj, prop, descriptor)这个API

  1. + var data = {
  2. + a: 1
  3. + }
  4. + Object.defineProperty(data, 'a', {// 为data中的a进行拦截,读取a的时候返回自己新建的_a的值,设置a的值的时候,设置到_a上。这样,开发者对a的操作,都会映射到我们新建的虚拟的_a变量上
  5. + configurable: true, // 是否允许删除属性,默认true
  6. + enumerable: true, // 是否允许遍历,默认true
  7. + get: function () {
  8. + console.log('我被读取了,返回了_a的值', this._a)
  9. + return this._a
  10. + },
  11. + set(value) {
  12. + // this.a = value;
  13. + this._a = value;
  14. + console.log('我被设置了,被设置的值为', this._a, '并放进了a的对象中')
  15. + }
  16. + })

在浏览器中,打开页面,并查看控制台,对data.a进行操作

  1. data.a myVue.js:8
  2. 我被读取了,返回了_a的值 undefined
  3. undefined
  4. ——————————————————————————————————————————————————————————————————————————————
  5. data.a = 10 myVue.js:14
  6. 我被设置了,被设置的值为 10 并放进了a的对象中
  7. 10
  8. ——————————————————————————————————————————————————————————————————————————————
  9. data.a myVue.js:8
  10. 我被读取了,返回了_a的值 10
  11. 10

可以看到,我们对data.a进行的操作,实际改变的变量是我们已经拦截的_a变量。

目前出现的问题是,第一次读取的时候,这个值没有被设置上,在下面来模拟解决方案

私有变量

声明概念_开头的变量一版为私有变量,外部无法访问,但是我们现在在控制台中输入并修改私有变量data._a

  1. data._a
  2. 10
  3. ——————————————————————————————————————————————————————————————————————————————
  4. data._a = 20
  5. 20
  6. ——————————————————————————————————————————————————————————————————————————————
  7. data._a
  8. 20
  9. ——————————————————————————————————————————————————————————————————————————————
  10. data.a myVue.js:8
  11. 我被读取了,返回了_a的值 20
  12. 20

却可以拿到私有变量中的_a的值,也可以进行无拦截的修改,这显然是我们所不希望的

所以我们可以为Object.defineProperty(obj, prop, descriptor)来进行封装一次,把我们理解的_a变成一个私有变量

修改myVue.js的内容为如下内容,

  1. var data = {
  2. a: 1
  3. }
  4. myDefineProperty(data, 'a')
  5. function myDefineProperty(obj,key){//对Object.defineProperty进行一次拦截,使外界无法访问私有变量value
  6. var value = obj[key];
  7. Object.defineProperty(obj,key,{// 为data增加
  8. configurable: true, // 是否允许删除属性,默认true
  9. enumerable: true, // 是否允许遍历,默认true
  10. get: function () {
  11. console.log('我被读取了,返回了value的值', value)
  12. return value
  13. },
  14. set(newValue) {
  15. value = newValue;
  16. console.log('我被设置了,被设置的值为', newValue, '并放进了value的对象中')
  17. }
  18. })
  19. }

然后再查看控制台

  1. data._a
  2. undefined
  3. ——————————————————————————————————————————————————————————————————————————————
  4. data.value
  5. undefined
  6. ——————————————————————————————————————————————————————————————————————————————
  7. data.a myVue.js:12
  8. 我被读取了,返回了value的值 1
  9. 1
  10. ——————————————————————————————————————————————————————————————————————————————

开发者就无法自行操作我们设计的私有变量value的内容了

自此,我们解决了,对一个对象属性的拦截,并且阻止了用户对我们设计的私有变量进行操作

双向绑定实践

我们知道了拦截属性之后,那么就进一步来实现,一个简单的双向绑定

我们修改一下index.html中的内容

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document</title>
  7. + <input type="text" @change='changeIpt'>
  8. + <p id='changeValue'></p>
  9. </head>
  10. <body>
  11. <script src="./js/myVue.js"></script>
  12. </body>
  13. </html>

并在myVue.js中,在set中添加双向绑定的操作

  1. var data = {
  2. a: 1
  3. }
  4. myDefineProperty(data, 'a')
  5. + var ipt = document.getElementById('ipt');
  6. + ipt.oninput = function(e){
  7. + data.a = e.target.value
  8. + }
  9. function myDefineProperty(obj,key){
  10. var value = obj[key];
  11. Object.defineProperty(obj,key,{// 为data增加
  12. configurable: true, // 是否允许删除属性,默认true
  13. enumerable: true, // 是否允许遍历,默认true
  14. get: function () {
  15. console.log('我被读取了,返回了value的值', value)
  16. return value
  17. },
  18. set(newValue) {
  19. value = newValue;
  20. + document.getElementById('iptValue').innerText = newValue;
  21. + ipt.value = newValue;
  22. console.log('我被设置了,被设置的值为', newValue, '并放进了value的对象中')
  23. }
  24. })
  25. }

然后我们在input框里输入内容,便表现出了双向绑定的能力。

点击查看demo

记得打开控制台哦!~下方为录制的屏幕,可能无法正常显示,可以点击上方demo来查看

觉得好的话,可以给我的 github点个star

从0开始探究vue-双向绑定原理的更多相关文章

  1. vue双向绑定原理分析

    当我们学习angular或者vue的时候,其双向绑定为我们开发带来了诸多便捷,今天我们就来分析一下vue双向绑定的原理. 简易vue源码地址:https://github.com/jiangzhenf ...

  2. vue双向绑定原理及实现

    vue双向绑定原理及实现 一.总结 一句话总结:vue中的双向绑定主要是通过发布者-订阅者模式来实现的 发布 订阅 1.单向绑定和双向绑定的区别是什么? model view 更新 单向绑定:mode ...

  3. Vue双向绑定原理(源码解析)---getter setter

       Vue双向绑定原理      大部分都知道Vue是采用的是对象的get 和set方法来实现数据的双向绑定的过程,本章将讨论他是怎么利用他实现的. vue双向绑定其实是采用的观察者模式,get和s ...

  4. [Vue源码]一起来学Vue双向绑定原理-数据劫持和发布订阅

    有一段时间没有更新技术博文了,因为这段时间埋下头来看Vue源码了.本文我们一起通过学习双向绑定原理来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫 ...

  5. Vue双向绑定原理,教你一步一步实现双向绑定

    当今前端天下以 Angular.React.vue 三足鼎立的局面,你不选择一个阵营基本上无法立足于前端,甚至是两个或者三个阵营都要选择,大势所趋. 所以我们要时刻保持好奇心,拥抱变化,只有在不断的变 ...

  6. vue 学习二 深入vue双向绑定原理

    vue双向绑定原理 请示总体来讲 就是为data的中的每个属性字段添加一个getter/seter属性 以此来追踪数据的变化,而执行这部操作,依赖的就是js的Object.defineProperty ...

  7. vue双向绑定原理

    要了解vue的双向绑定原理,首先得了解Object.defineProperty()方法,因为访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过 Object.definePrope ...

  8. Vue双向绑定原理及其实现

    在之前面试的时候被面试官问到是否了解Vue双向绑定的原理,其实自己之前看过双向绑定的原理,但也就是粗略的了解,但是没有深入.面试官当时让我手写一个原理,但是就蒙了

  9. 通俗易懂了解Vue双向绑定原理及实现

    看到一篇文章,觉得写得挺好的,拿过来给大家分享一下,刚好解答了一些困扰我的一些疑惑!!! 1. 前言 每当被问到Vue数据双向绑定原理的时候,大家可能都会脱口而出:Vue内部通过Object.defi ...

随机推荐

  1. FAXCOM和FXSCOMEX 传真编程

    需要引用的dl,如下信息,早起使用的是FXSCOM.DLL,现在微软提供了相应的扩展,其程序集为,FXSCOMEX.dll FXSCOMEX.dll 提供跟加健全的方法,可以说所有关于传真的操作都在这 ...

  2. Mysql常用sql语句(16)- inner join 内连接

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 利用条件表达式来消除交叉连接(cross joi ...

  3. hdu5381 The sum of gcd]莫队算法

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=5381 思路:这个题属于没有修改的区间查询问题,可以用莫队算法来做.首先预处理出每个点以它为起点向左和向右连 ...

  4. android 百度地图v3.2.0获取实际地址

    百度地图升级到v3.2.0后,api发生挺大的变化的,但是下载的Demo却不是最新版本的. 在v3.2.0之前获取详细地址只要:option.setIsNeedAddress(true); 但是升级后 ...

  5. 学习ASP.NET Core(06)-Restful与WebAPI

    上一篇我们使用Swagger添加了接口文档,使用Jwt完成了授权,本章我们简答介绍一下RESTful风格的WebAPI开发过程中涉及到的一些知识点,并完善一下尚未完成的功能 .NET下的WebAPI是 ...

  6. webpack4多页应用HTML按需添加入口依赖chunk【html-webpack-plugin & html-inline-entry-chunk-plugin】

    在webpack4中使用splitChunkPlugin时,根据需要将公共代码拆分为多个依赖后,需要在创建htmlWebpackPlugin时候按需引入对应入口文件依赖的chunk.但是html-we ...

  7. 00001- layui 表格的默认工具栏添加自定义按钮

    首先定义table: var tableIns = table.render({ elem:'#businessUserListTable' ,url: ctx+'/business/business ...

  8. Django之MTV模式

    MTV与MVC+url控制器 MVC框架: ·         M:model.py  就是和数据库打交道用的,创建表等操作 ·         V:View  视图(视图函数:逻辑处理响应函数,ht ...

  9. docker基本维护命令

    docker search centos ##查服务器上面的镜像:docker images ##查本地的镜像.docker pull centos ##拉镜像. docker run centos ...

  10. jquery 1.9版本下复选框 全选/取消实现

    http://zhangzhaoaaa.iteye.com/blog/1914497 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Tran ...