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 二维数组的实现与应用
Mar 16 Javascript
初学js 新节点的创建 删除 的步骤
Jul 04 Javascript
javascript时区函数介绍
Sep 14 Javascript
在jQuery中 常用的选择器介绍
Apr 16 Javascript
JS测试显示屏分辨率以及屏幕尺寸的方法
Nov 22 Javascript
jQuery实现统计复选框选中数量
Nov 24 Javascript
js获取时间并实现字符串和时间戳之间的转换
Jan 05 Javascript
JavaScript匿名函数用法分析
Feb 13 Javascript
jQuery实现的放大镜效果示例
Sep 13 Javascript
Node.js使用supervisor进行开发中调试的方法
Mar 26 Javascript
Vue实现导航栏点击当前标签变色功能
Aug 19 Javascript
jQuery--遍历操作实例小结【后代、同胞及过滤】
May 22 jQuery
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
Access数据库导入Mysql的方法之一
2006/10/09 PHP
整理的一些实用WordPress后台MySQL操作命令
2013/01/07 PHP
PHP弱类型的安全问题详细总结
2016/09/25 PHP
PHP使用Redis替代文件存储Session的方法
2017/02/15 PHP
asp函数split()对应php函数explode()
2019/02/27 PHP
javascript基础知识大集锦(二) 推荐收藏
2011/01/13 Javascript
基于jQuery的输入框无值自动显示指定数据的实现代码
2011/01/24 Javascript
javascript返回顶部效果(自写代码)
2013/01/06 Javascript
Jquery通过Ajax访问XML数据的小例子
2013/11/18 Javascript
javascript 处理null及null值示例
2014/06/09 Javascript
node.js中的http.get方法使用说明
2014/12/14 Javascript
深入理解js数组的sort排序
2016/05/28 Javascript
js 将input框中的输入自动转化成半角大写(税号输入框)
2017/02/16 Javascript
jquery拼接ajax 的json和字符串拼接的方法
2017/03/11 Javascript
js中的触发事件对象event.srcElement与event.target详解
2017/03/15 Javascript
JavaScript简单计算人的年龄示例
2017/04/15 Javascript
微信小程序实现折叠与展开文章功能
2018/06/12 Javascript
[42:52]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
Python 网络编程起步(Socket发送消息)
2008/09/06 Python
Python实现3行代码解简单的一元一次方程
2014/08/18 Python
python 链接和操作 memcache方法
2017/03/04 Python
基于python绘制科赫雪花
2018/06/22 Python
Python调用C++,通过Pybind11制作Python接口
2018/10/16 Python
python 数据分析实现长宽格式的转换
2020/05/18 Python
详解用Python调用百度地图正/逆地理编码API
2020/07/02 Python
Selenium Webdriver元素定位的八种常用方式(小结)
2021/01/13 Python
墨西哥运动服饰和鞋网上商店:Netshoes墨西哥
2016/07/28 全球购物
土耳其新趋势女装购物网站:Addax
2020/01/07 全球购物
是否有自动比较结构的方法
2015/06/03 面试题
怎样写留学自荐信
2013/11/11 职场文书
检察官就职演讲稿
2014/01/13 职场文书
ktv总经理岗位职责
2014/02/17 职场文书
竞聘上岗演讲
2014/05/19 职场文书
英语教师个人工作总结
2015/02/09 职场文书
医院办公室主任岗位职责
2015/04/01 职场文书
Python序列化模块JSON与Pickle
2022/06/05 Python