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 播放器 控制
Jan 22 Javascript
json 入门基础教程 推荐
Oct 31 Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
Apr 07 Javascript
js querySelector和getElementById通过id获取元素的区别
Apr 20 Javascript
当自定义数据属性为json格式字符串时jQuery的data api问题探讨
Feb 18 Javascript
jQuery实现列表自动循环滚动鼠标悬停时停止滚动
Sep 06 Javascript
检查输入的是否是数字使用keyCode配合onkeypress事件
Jan 23 Javascript
jQuery中ajax和post处理json的不同示例对比
Nov 02 Javascript
JS实现复制内容到剪贴板功能兼容所有浏览器(推荐)
Jun 17 Javascript
JavaScript字符集编码与解码详谈
Feb 02 Javascript
jQuery插件HighCharts实现2D柱状图、折线图的组合多轴图效果示例【附demo源码下载】
Mar 09 Javascript
VsCode与Node.js知识点详解
Sep 05 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
福利彩票幸运号码自动生成器
2006/10/09 PHP
elgg 获取文件图标地址的方法
2010/03/20 PHP
php使用smtp发送支持附件的邮件示例
2014/04/13 PHP
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
2014/07/01 PHP
php实现的简单日志写入函数
2015/03/31 PHP
windows7配置Nginx+php+mysql的详细教程
2016/09/04 PHP
一个很简单的办法实现TD的加亮效果.
2006/06/29 Javascript
使用 JScript 创建 .exe 或 .dll 文件的方法
2011/07/13 Javascript
Jquery 自定义动画概述及示例
2013/03/29 Javascript
使用JavaScript 编写简单计算器
2014/11/24 Javascript
原生 JS Ajax,GET和POST 请求实例代码
2016/06/08 Javascript
js实现简单的网页换肤效果
2017/01/18 Javascript
原生javascript实现分页效果
2017/04/21 Javascript
简单谈谈关于Angular Cli打包的事
2017/09/05 Javascript
AngularJs 最新验证手机号码的实例,成功测试通过
2017/11/26 Javascript
nodejs实现爬取网站图片功能
2017/12/14 NodeJs
Angular 组件之间的交互的示例代码
2018/03/24 Javascript
vue+springboot图片上传和显示的示例代码
2020/02/14 Javascript
Nest.js 授权验证的方法示例
2021/02/22 Javascript
Python二分法搜索算法实例分析
2015/05/11 Python
python监控文件或目录变化
2016/06/07 Python
Python可变参数用法实例分析
2017/04/02 Python
CentOS中升级Python版本的方法详解
2017/07/10 Python
numpy 对矩阵中Nan的处理:采用平均值的方法
2018/10/30 Python
python使用zip将list转为json的方法
2018/12/31 Python
Python Django搭建网站流程图解
2020/06/13 Python
python语音识别指南终极版(有这一篇足矣)
2020/09/09 Python
ColourPop美国官网:卡拉泡泡,洛杉矶彩妆品牌
2019/04/28 全球购物
英国老牌潮鞋店:Offspring
2019/08/19 全球购物
师范教师专业大学生职业生涯规划范文
2014/03/02 职场文书
企业金融服务方案
2014/06/03 职场文书
公安纪律作风整顿剖析材料
2014/10/10 职场文书
2015国庆节66周年演讲稿
2015/03/20 职场文书
教师调动申请报告
2015/05/18 职场文书
2015年教学副校长工作总结
2015/07/22 职场文书
go语言-在mac下brew升级golang
2021/04/25 Golang