vue使用Proxy实现双向绑定的方法示例


Posted in Javascript onMarch 20, 2019

前言:vue3.0要用Proxy来实现双向绑定,因此先来尝试一下实现方法。

1 Object.defineProperty 实现

原来vue2的实现使用Object.defineProperty,监听set,但对于数组直接下标给数组设置值监听不了。

function observe(data) {
 if (!data || typeof data !== 'object') {
   return;
 }
 // 取出所有属性遍历
 Object.keys(data).forEach(function(key) {
   defineReactive(data, key, data[key]);
 });
};

function defineReactive(data, key, val) {
 observe(val); // 监听子属性
 Object.defineProperty(data, key, {
   enumerable: true, // 可枚举
   configurable: false, // 不能再重写defineProperty
   get: function() {
     return val;
   },
   set: function(newVal) {
     console.log('-------通知订阅者--------')
     val = newVal;
   }
 });
}

2 使用Proxy实现

使用Proxy实现原理主要是new一个Proxy对象,代理你的data值,需要注意的一点是,对于数组的方法操作来说,会产生两次赋值操作,一次是添加值,一次是改变他的length值,而对于Object.defineProperty监听不到的数组下标给数组设置值,Proxy是可以监听到的。

function observe(data) {
  if (!data || typeof data !== 'object') {
    return;
  }
  // 取出所有属性遍历
  Object.keys(data).forEach(function(_k) {
    // Proxy不允许绑定在非对象上
    if (data[_k] && typeof data[_k] === 'object') {
      data[_k] = defineReactive(data[_k]);
    }
  });
}

function defineReactive(data) {
 return new Proxy(data, {
  set(target, key, value, proxy) {
    // 进行数组操作时,会进行两次set 一次数据改变,一次length改变,两次改变data的值是不变,因此不应该多分发一次消息
   if (
    Object.prototype.toString.call(data) === "[object Array]" &&
    key === "length"
   ) {
    Reflect.set(target, key, value, proxy);
    return true;
   }
   observe(data);
   Reflect.set(target, key, value, proxy);
   console.log('-------通知订阅者--------')
   return true;
  }
 });

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript高级程序设计(第3版)学习笔记11 内建js对象
Oct 11 Javascript
js弹出的对话窗口永远保持居中显示
Dec 15 Javascript
js 控制页面跳转的5种方法
Sep 09 Javascript
js与jQuery 获取父窗、子窗的iframe
Dec 20 Javascript
jquery实现动态操作select选中
Feb 11 Javascript
jquery 中ajax执行的优先级
Jun 22 Javascript
jQuery实现的简单在线计算器功能
May 11 jQuery
Vue服务器渲染Nuxt学习笔记
Jan 31 Javascript
JavaScript异步加载问题总结
Feb 17 Javascript
详解vue项目打包后通过百度的BAE发布到网上的流程
Mar 05 Javascript
JavaScript去掉数组重复项的方法分析【测试可用】
Jul 19 Javascript
在vue项目中优雅的使用SVG的方法实例详解
Dec 03 Javascript
vue实现可视化可拖放的自定义表单的示例代码
Mar 20 #Javascript
详解JavaScript作用域和作用域链
Mar 19 #Javascript
vue双向绑定及观察者模式详解
Mar 19 #Javascript
Vue2.0+Vux搭建一个完整的移动webApp项目的示例
Mar 19 #Javascript
在vue中使用G2图表的示例代码
Mar 19 #Javascript
Three.js中矩阵和向量的使用教程
Mar 19 #Javascript
vue+iview动态渲染表格详解
Mar 19 #Javascript
You might like
浅析Dos下运行php.exe,出现没有找到php_mbstring.dll 错误的解决方法
2013/06/29 PHP
利用Homestead快速运行一个Laravel项目的方法详解
2017/11/14 PHP
PHP生成腾讯云COS接口需要的请求签名
2018/05/20 PHP
Laravel 5.1 框架Blade模板引擎用法实例分析
2020/01/04 PHP
将HTMLCollection/NodeList/伪数组转换成数组的实现方法
2011/06/20 Javascript
js字符编码函数区别分析
2011/12/28 Javascript
利用ajaxfileupload插件实现文件上传无刷新的具体方法
2013/06/08 Javascript
JS注释所产生的bug 即使注释也会执行
2013/11/19 Javascript
JavaScript跨域方法汇总
2014/10/16 Javascript
JavaScript每天定时更换皮肤样式的方法
2015/07/01 Javascript
详解JavaScript数组过滤相同元素的5种方法
2017/05/23 Javascript
关于TypeScript中import JSON的正确姿势详解
2017/07/25 Javascript
微信小程序报错:this.setData is not a function的解决办法
2017/09/27 Javascript
JS实现常见的查找、排序、去重算法示例
2018/05/21 Javascript
layui原生表单验证的实例
2019/09/09 Javascript
Vue开发环境跨域访问问题
2020/01/22 Javascript
[01:33]一分钟玩转DOTA2第三弹:DOTA2&DotA快捷操作大对比
2014/06/04 DOTA
python list 合并连接字符串的方法
2013/03/09 Python
Python标准库之循环器(itertools)介绍
2014/11/25 Python
Python网站验证码识别
2016/01/25 Python
Python实现邮件的批量发送的示例代码
2018/01/23 Python
Python中collections模块的基本使用教程
2018/12/07 Python
Python验证码截取识别代码实例
2020/05/16 Python
python numpy实现rolling滚动案例
2020/06/08 Python
Python面向对象特殊属性及方法解析
2020/09/16 Python
详解用python -m http.server搭一个简易的本地局域网
2020/09/24 Python
CSS3样式linear-gradient的使用实例
2017/01/16 HTML / CSS
CSS3制作圆形滚动进度条动画的示例
2020/11/05 HTML / CSS
HTML5中form如何关闭自动完成功能的方法
2018/07/02 HTML / CSS
关键字final的用法
2013/10/02 面试题
大二自我鉴定范文
2013/10/05 职场文书
《一件运动衫》教学反思
2014/02/19 职场文书
群众路线党员个人剖析材料
2014/10/08 职场文书
购房委托书
2014/10/15 职场文书
行政人事主管岗位职责
2015/04/11 职场文书
Android基础入门之dataBinding的简单使用教程
2022/06/21 Java/Android