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执行效率全面总结
Nov 04 Javascript
21个值得收藏的Javascript技巧
Feb 04 Javascript
JS将滑动门改为选项卡(需鼠标点击)的实现方法
Sep 27 Javascript
jQuery模拟Marquee实现无缝滚动效果完整实例
Sep 29 Javascript
浅析JavaScriptSerializer类的序列化与反序列化
Nov 22 Javascript
JavaScript实现简单的四则运算计算器完整实例
Apr 28 Javascript
使用jQuery.Pin垂直滚动时固定导航
May 24 jQuery
详解webpack+vue-cli项目打包技巧
Jun 17 Javascript
Vue触发式全局组件构建的方法
Nov 28 Javascript
JS闭包经典实例详解
Dec 20 Javascript
jQuery实现简单日历效果
Jul 05 jQuery
利用promise及参数解构封装ajax请求的方法
Mar 24 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通过正则表达式下载图片到本地的实现代码
2011/09/19 PHP
php 生成签名及验证签名详解
2016/10/26 PHP
网易JS面试题与Javascript词法作用域说明
2010/11/09 Javascript
passwordStrength 基于jquery的密码强度检测代码使用介绍
2011/10/08 Javascript
Enter转换为Tab的小例子(兼容IE,Firefox)
2013/11/14 Javascript
asm.js使用示例代码
2013/11/28 Javascript
JQuery的$和其它JS发生冲突的快速解决方法
2014/01/24 Javascript
Jquery 监视按键,按下回车键触发某方法的实现代码
2014/05/11 Javascript
jQuery实现的数值范围range2dslider选取插件特效多款代码分享
2015/08/27 Javascript
jQuery实现根据生日计算年龄 星座 生肖
2016/11/23 Javascript
移动端刮刮乐的实现方式(js+HTML5)
2017/03/23 Javascript
详解js静态资源文件请求的处理
2017/08/01 Javascript
layui中layer前端组件实现图片显示功能的方法分析
2017/10/13 Javascript
jQuery实现数字自动增加或者减少的动画效果示例
2018/12/11 jQuery
jQuery操作选中select下拉框的值代码实例
2020/02/07 jQuery
Python数组定义方法
2016/04/13 Python
python使用标准库根据进程名如何获取进程的pid详解
2017/10/31 Python
浅谈flask中的before_request与after_request
2018/01/20 Python
解决Python下json.loads()中文字符出错的问题
2018/12/19 Python
python的re模块使用方法详解
2019/07/26 Python
python实现从wind导入数据
2019/12/03 Python
Pyqt助手安装PyQt5帮助文档过程图解
2020/11/20 Python
css3 pointer-events 介绍详解
2017/09/18 HTML / CSS
英国领先的运动物理治疗供应公司:Vivomed
2018/07/14 全球购物
我的珠宝盒:Ma boîte à bijoux
2019/08/27 全球购物
平面设计专业大学生职业规划书
2014/03/12 职场文书
书法大赛策划方案
2014/06/04 职场文书
应届毕业生求职信范文
2014/07/07 职场文书
2015年度房地产工作总结
2015/04/09 职场文书
2015年组织委员工作总结
2015/04/23 职场文书
父亲去世追悼词
2015/06/23 职场文书
2019餐饮行业创业计划书!
2019/06/27 职场文书
Django drf请求模块源码解析
2021/06/08 Python
使用JS实现简易计算器
2021/06/14 Javascript
Python制作一个随机抽奖小工具的实现
2021/07/07 Python
一篇文章弄懂Python中的内建函数
2021/08/07 Python