众所周知,Vue的两大重要概念:

  1. 数据驱动
  2. 组件系统

接下来我们浅析数据双向绑定的原理

一、vue2

1、认识defineProperty

vue2中的双向绑定是基于definePropertyget操作set操作,那么我们简单认识下defineProperty
作用: 就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。
那么我们先来看下Object.getOwnPropertyDescriptor(),有定义方法就会有获取方法,对这就是与defineProperty相对的方法,它可以获取属性值。

var a ={b:1,c:2
}
console.log(Object.getOwnPropertyDescriptor(a,'b')); //查看获取b属性


这就是打印出来的结果,configurable的意思是可便利,enumerable的意思是可枚举,writable的意思是可写。

2、使用defineProperty实现简单的私有变量

知道了属性内部的属性值,我们可以使用defineProperty来实现一个私有变量。

var a ={b:1,c:2
}
Object.defineProperty(a,'b',{writable:false  //不可写
})
console.log(Object.getOwnPropertyDescriptor(a,'b')); //查看获取b属性


发现,改变不了a.b的值。


另外,还可以使用一个很快捷的方法实现私有变量

var a ={b:1,c:2
}
Object.freeze(a,'b'); //冻结,可理解为变为私有属性
// Object.seal(a,'b'); //configurable置为false
console.log(Object.getOwnPropertyDescriptor(a,'b')); //查看获取b属性


同样,writable为false。如果使用seal()只能使configurable为false。

3、简单认识defineProperty的get、set的方法

我们先不要创建全局变量,跟get方法return值,你会发现值为undefined

于是我们改了改

var a ={b:1,c:2
}var _value=a.b; //b值赋值需要先赋给全局变量,不然使用不了Object.defineProperty(a,'b',{get:function(){console.log('get');return _value; // get方法必须ruturn值,值为全局变量。},set:function(newValue){console.log(newValue)_value=newValue; // 赋值}})


取到了。

4、使用defineProperty简单实现Vue双向绑定

test.js

// 使用defineProperty
function vue () {this.$data={a:1 // 数组的话不会更新};this.el=document.getElementById('app');this._html="";this.observe(this.$data);this.render();
};
vue.prototype.observe=function(obj){var value;var self=this;for(var key in obj){value =obj[key];if(typeof value === 'object'){this.observe(value)}else{Object.defineProperty(this.$data,key,{get:function(){return value;},set:function(newvalue){value=newvalue;self.render();}})}}
}
vue.prototype.render=function(){this._html='I am '+ this.$data.a;this.el.innerHTML=this._html;
}// ***************************************
//数组改变更新,装饰者模式
// var arraypro=Array.prototype;
// var arrayob=Object.create(arraypro);
// var arr = ["push","pop","shift"];
// // arr里的方法,既能保持原有的方法,又能触发更新。
// arr.forEach(function(method,index){//     arrayob[method]=function(){//         var ret=arraypro[method].apply(this,arguments);
//         console.log('更新');
//         return ret;
//     }
// })
// var arr=[];
// arr.__proto__=arrayob;
// arr.push(1);

test.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>vue双向绑定原理</title>
</head>
<body><div id="app"></div>
</body>
<script src="test.js"></script>
<script>var vm = new vue();setTimeout(function(){console.log('changes');console.log(vm.$data);vm.$data.a=222;},2000)
</script>
</html>

这样我们就简单实现了数据双向绑定。

二、vue3

1、简单认识Proxy

就是一种机制,用来拦截外界对目标对象的访问,可以对这些访问进行过滤或者改写,所以Proxy更像是目标对象的代理器。

var ob= {a:1,b:2
}
// 新创建一个Proxy对象直接替换ob对象
ob=new Proxy(ob,{get:function(target,key,receive){   // target指的是原始对象,key指的是属性值,receive指的是这个Proxy对象console.log(target,key,receive) return target[key]; //get方法 依然需要return},set:function(target,key,newvalue,receive){console.log(target,key,newvalue,receive) // newvalue指新创建的值target[key]=newvalue;}
});

这里需要注意的是:第一次使用proxy时,在new的时候把原对象替换掉。就会触发get方法

看到上方的代码,我们可以总结Proxy的几个优点:

  1. defineProperty只能监听某个属性,不能对全对象监听;
  2. 所以可以省去for in 提升效率;
  3. 可以监听数组,不用再去单独的对数组做异性操作。

2、使用Proxy简单实现数据双向绑定

test1.js

// 使用Proxy
function vue () {this.$data={a:1 };this.el=document.getElementById('app');this._html="";this.observe(this.$data);this.render();
};
vue.prototype.observe=function(obj){var self=this;this.$data=new Proxy(this.$data,{get:function(target,key){return target[key];},set:function(target,key,newvalue){target[key]=newvalue;self.render();}})
}
vue.prototype.render=function(){this._html='I am '+ this.$data.a;this.el.innerHTML=this._html;
}

test.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>vue双向绑定原理</title>
</head>
<body><div id="app"></div>
</body>
<script src="test1.js"></script>
<script>var vm = new vue();setTimeout(function(){console.log('changes');console.log(vm.$data);vm.$data.a=222;},2000)
</script>
</html>

3、Proxy还可以做什么呢?

(1)、校验类型

function createValidator(target,validator){return new Proxy(target,{_validator:validator,set:function(target,key,value,proxy){if (target.hasOwnProperty(key)) {var validator1=this._validator[key];if(validator1(value)){return Reflect.set(target,key,value,proxy)}else{throw Error('type error')}}}})
}
var personvalidator={name(val){return typeof val==='string'},age(val){return typeof val==='number'&&val>18}
}class Person {constructor(name,age) {this.name=name;this.age=age;return createValidator(this,personvalidator);}
}
var tss=new Person('maomin',22);

(2)、真正私有变量

var api = {_secret: 'xxxx',_otherSec: 'bbb',ver: 'v0.0.1'
};api = new Proxy(api, {get: function (target, key) {// 以 _ 下划线开头的都认为是 私有的if (key.startsWith('_')) {console.log('私有变量不能被访问');return false;}return target[key];},set: function (target, key, value) {if (key.startsWith('_')) {console.log('私有变量不能被修改');return false;}target[key] = value;},has: function (target, key) {return key.startsWith('_') ? false : (key in target);}
});api._secret; // 私有变量不能被访问
console.log(api.ver); // v0.0.1
api._otherSec = 3; // 私有变量不能被修改
console.log('_secret' in api); //false
console.log('ver' in api); //true

Vue数据双向绑定原理(vue2向vue3的过渡)相关推荐

  1. this指向-作用域、作用域链-预解析 变量提升-Vue组件传值 父子 子父 非父子-Vue数据双向绑定原理

    目录 this指向 作用域.作用域链 预解析 变量提升 Vue组件传值 父子 子父 非父子 Vue数据双向绑定原理 1.this指向 函数的this指向 看调用.不看声明 (1)普通函数调用 ①函数名 ...

  2. 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分

    最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理. 情景再现: 当我手机铃声响 ...

  3. vue数据双向绑定原理

    vue 双向绑定原理 官网–https://cn.vuejs.org/v2/guide/reactivity.html 1.vue双向数据绑定是 通过 数据劫持 并结合 发布-订阅模式 的方法来实现的 ...

  4. vue的双向绑定原理及实现

    前言 使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,所以这次特意花了几晚时间查阅资料和阅读相关源码,自己也实现一个简单版vue的双向绑定版本,先上个成果图 ...

  5. 基于Vue2.0数据双向绑定原理-详解

    在线使用-线上测试-源码 //代码: <div id="app"><input v-model="name" type="text& ...

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

    vue数据双向绑定的原理 一 复习闭包 1 闭包含义: 当函数嵌套时,内部函数使用了外部函数的变量,就会产生闭包 当函数可以记住并访问自己的作用域时,就会产生闭包 2 闭包注意点 ① 队列里的代码执行 ...

  7. 记录vue的双向绑定原理及实现

    这里写自定义目录标题 思路分析 实现过程 1.实现一个Observer 2.实现Watcher 此文章是学习以为大神____chen的 <vue的双向绑定原理及实现> vue数据双向绑定是 ...

  8. vue 的双向绑定原理

    目录 一.一句话描述 vue 的双向绑定原理 二.细说 vue 的双向绑定原理 1.vue 2.x 的双向绑定 2.vue 3.x 的双向绑定 3.一个完整的案例 一.一句话描述 vue 的双向绑定原 ...

  9. 小猿圈解析vue数据双向绑定的缺点

    vue是当今前端很流行的一种框架,但是vue也是有一定的缺陷的,你有过了解吗?下面小猿圈web前端老师就为你解析一下vue数据双向绑定的缺陷,希望对你有所帮助,下面我们一起了解一下吧. 1.vue 实 ...

最新文章

  1. STM32F103ZET6 蜂鸣器、按键
  2. Package ‘*****‘ has no installation candidate
  3. android 仿微信朋友圈 评论,2020年android 仿微信朋友圈 评论
  4. 理想汽车7月交付8589辆理想ONE 单月交付量首次超8000辆
  5. linux空间支持伪静态,[转载]Linux下nginx支持.htaccess文件实现伪静态的方法
  6. java icache_java手写多级缓存
  7. 探索私有云OpenStack管理选项
  8. 学习ARM64页表转换流程
  9. numpy array和python list_Python list与NumPy array 区分详解
  10. 几个不错的网站(转)
  11. 4.4 matlab三维曲线(plot3函数、fplot3函数)
  12. Playwright选择器
  13. 国内CDN加速的背景和现状
  14. android卡刷教程,卡刷是什么意思?安卓系统卡刷教程详解
  15. 华为nova6se怎么升级鸿蒙,华为EMUI11支持哪些手机
  16. Arcgis选择自己想要的区域地图
  17. SpringBoot @Bean
  18. docker容器搭建discuz论坛
  19. Windows 10 打印机驱动无法删除和卸载的解决办法
  20. 匿怨而友其人,左丘明耻之,丘亦耻之。我不是圣人,我假装什么都没发生。

热门文章

  1. HTTP Status 404 – 未找到:源服务器未能找到目标资源的表示或者是不愿公开一个已经存在的资源表示。
  2. docker| docker/dockerfile 所有知识点,从头开始(更新完)
  3. NR的帧结构以及子载波间隔、时隙、符号
  4. cad转dxf格式文件太大_CAD转DXF怎么转换?教你三种转换方法
  5. Nginx-基本概念和原理
  6. 基于YRCloudFile容器存储的WordPress HA部署方案
  7. Dell venue 8 pro 打造全功能机
  8. 后盾网-CI框架实例教程-马振宇 - 学习笔记(3)
  9. Javascript 处理二进制数据:JavaScript typed arrays
  10. x86架构与ARM架构(AGX、TX2、NX等)下配置带ROS插件的QtCreator(Qt+ROS+ubuntu18)(源码编译安装方式)