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 相关文章推荐
jQuery方法简洁实现隔行换色及toggleClass的使用
Mar 15 Javascript
使用原生js封装webapp滑动效果(惯性滑动、滑动回弹)
May 06 Javascript
js window对象属性和方法相关资料整理
Nov 11 Javascript
如何使用jquery easyui创建标签组件
Nov 18 Javascript
详解js图片轮播效果实现原理
Dec 17 Javascript
JavaScript+html5 canvas绘制的圆弧荡秋千效果完整实例
Jan 26 Javascript
微信小程序 实战程序简易新闻的制作
Jan 09 Javascript
jQuery EasyUI开发技巧总结
Sep 26 jQuery
vue中进入详情页记住滚动位置的方法(keep-alive)
Sep 21 Javascript
Vue的H5页面唤起支付宝支付功能
Apr 18 Javascript
微信小程序图片左右摆动效果详解
Jul 13 Javascript
JS在Array数组中按指定位置删除或添加元素对象方法示例
Nov 19 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
php隐藏IP地址后两位显示为星号的方法
2014/11/21 PHP
Yii框架form表单用法实例
2014/12/04 PHP
浅析PHP文件下载原理
2014/12/25 PHP
php自动获取关键字的方法
2015/01/06 PHP
php内嵌函数用法实例
2015/03/20 PHP
PHP性能分析工具xhprof的安装使用与注意事项
2017/12/19 PHP
PHP7中I/O模型内核剖析详解
2019/04/14 PHP
一文看懂PHP进程管理器php-fpm
2020/06/01 PHP
js压缩利器
2007/02/20 Javascript
javascript之卸载鼠标事件的代码
2007/05/14 Javascript
jquery 经典动画菜单效果代码
2010/01/26 Javascript
给Flash加一个超链接(推荐使用透明层)兼容主流浏览器
2013/06/09 Javascript
深入解析JavaScript中的变量作用域
2013/12/06 Javascript
jQuery插件ImageDrawer.js实现动态绘制图片动画(附源码下载)
2016/02/25 Javascript
JQuery 在文档中查找指定name的元素并移除的实现方法
2016/05/19 Javascript
JS基于构造函数实现的菜单滑动显隐效果【测试可用】
2016/06/21 Javascript
解析AngularJS中get请求URL出现的跨域问题
2016/12/01 Javascript
JS跨域请求外部服务器的资源
2017/02/06 Javascript
JS使用ActiveXObject实现用户提交表单时屏蔽敏感词功能
2017/06/20 Javascript
深入理解React Native原生模块与JS模块通信的几种方式
2017/07/24 Javascript
微信小程序自定义波浪组件使用方法详解
2019/09/21 Javascript
微信小程序 导入图标实现过程详解
2019/10/11 Javascript
[42:52]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
pymssql ntext字段调用问题解决方法
2008/12/17 Python
Python实现在matplotlib中两个坐标轴之间画一条直线光标的方法
2015/05/20 Python
Python的Django框架中URLconf相关的一些技巧整理
2015/07/18 Python
python实时分析日志的一个小脚本分享
2017/05/07 Python
numpy自动生成数组详解
2017/12/15 Python
python 字典访问的三种方法小结
2019/12/05 Python
python中操作文件的模块的方法总结
2021/02/04 Python
html2 canvas生成清晰的图片实现打印功能
2019/09/23 HTML / CSS
Halston Heritage官网:简洁的日装,稍显奢华的晚装
2018/11/20 全球购物
五一口号
2014/06/19 职场文书
员工三分钟演讲稿
2014/08/19 职场文书
2014年个人工作总结模板
2014/12/15 职场文书
2015年化妆品销售工作总结
2015/05/11 职场文书