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 相关文章推荐
syntaxhighlighter 使用方法
Jul 02 Javascript
jQuery 扩展对input的一些操作方法
Oct 30 Javascript
鼠标滑过出现预览的大图提示效果
Feb 26 Javascript
JS实现图片延迟加载并淡入淡出效果的简单方法
Aug 25 Javascript
AngularJS使用自定义指令替代ng-repeat的方法
Sep 17 Javascript
jQuery上传多张图片带进度条样式(DEMO)
Mar 02 Javascript
jQuery插件HighCharts实现的2D对数饼图效果示例【附demo源码下载】
Mar 09 Javascript
javascript Function函数理解与实战
Dec 01 Javascript
jQuery实现滚动到底部时自动加载更多的方法示例
Feb 18 jQuery
vue添加class样式实例讲解
Feb 12 Javascript
手写Vue弹窗Modal的实现代码
Sep 11 Javascript
React自定义hook的方法
Jun 25 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执行速度全攻略
2006/10/09 PHP
php中批量修改文件后缀名的函数代码
2011/10/23 PHP
php中遍历二维数组并以表格的形式输出的方法
2017/01/03 PHP
Laravel框架实现model层的增删改查(CURD)操作示例
2018/05/12 PHP
PHP使用CURL实现下载文件功能示例
2019/06/03 PHP
javascript+xml技术实现分页浏览
2008/07/27 Javascript
javascript的onchange事件与jQuery的change()方法比较
2009/09/28 Javascript
javascript与CSS复习(二)
2010/06/29 Javascript
多浏览器兼容性比较好的复制到剪贴板的js代码
2011/10/09 Javascript
JQuery循环滚动图片代码
2011/12/08 Javascript
javascript抖动元素的小例子
2013/10/28 Javascript
js动态修改input输入框的type属性(实现方法解析)
2013/11/13 Javascript
详谈JavaScript 匿名函数及闭包
2014/11/14 Javascript
jQuery Ajax调用WCF服务详细教程
2015/03/31 Javascript
Angular.js之作用域scope'@','=','&'实例详解
2017/02/28 Javascript
Vue.js之slot深度复制详解
2017/03/10 Javascript
vue中将网页打印成pdf实例代码
2017/06/15 Javascript
写给小白看的JavaScript异步
2017/11/29 Javascript
基于jquery.page.js实现分页效果
2018/01/01 jQuery
深入浅析AngularJs模版与v-bind
2018/07/06 Javascript
JS实现的简单分页功能示例
2018/08/23 Javascript
浅谈JavaScript 代码简洁之道
2019/01/09 Javascript
JS使用new操作符创建对象的方法分析
2019/05/30 Javascript
jQuery弹框插件使用方法详解
2020/05/26 jQuery
vue-iview动态新增和删除的方法
2020/06/17 Javascript
PyCharm代码格式调整方法
2018/05/23 Python
Flask框架学习笔记之消息提示与异常处理操作详解
2019/08/15 Python
使用python-pptx包批量修改ppt格式的实现
2020/02/14 Python
基于Python的接口自动化unittest测试框架和ddt数据驱动详解
2021/01/27 Python
Peter Alexander新西兰站:澳大利亚领先的睡衣设计师品牌
2016/12/10 全球购物
美国高级音响品牌:Master&Dynamic
2018/07/05 全球购物
机械个人求职信范文
2014/01/24 职场文书
《凡卡》教学反思
2014/04/09 职场文书
八项规定对照检查材料
2014/08/31 职场文书
导游词之山西关帝庙
2019/11/01 职场文书
MySql如何将查询的出来的字段进行转换
2022/06/14 MySQL