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使用手册之二 DOM操作
Mar 24 Javascript
extjs 04_grid 单击事件新发现
Nov 27 Javascript
jquery实现树形二级菜单实例代码
Nov 20 Javascript
JavaScript eval() 函数介绍及应用示例
Jul 29 Javascript
Vuejs第一篇之入门教程详解(单向绑定、双向绑定、列表渲染、响应函数)
Sep 09 Javascript
Vuex 在Vue 组件中获得Vuex 状态state的方法
Aug 27 Javascript
vue项目动态设置页面title及是否缓存页面的问题
Nov 08 Javascript
js实现图片局部放大效果详解
Mar 18 Javascript
vxe-table vue table 表格组件功能
May 26 Javascript
超轻量级的js时间库miment使用解析
Aug 02 Javascript
微信小程序加载机制及运行机制图解
Nov 27 Javascript
vue element-ui中table合计指定列求和实例
Nov 02 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
星际争霸秘籍
2020/03/04 星际争霸
PHP实现二叉树的深度优先与广度优先遍历方法
2015/09/28 PHP
thinkphp3.2点击刷新生成验证码
2016/02/16 PHP
PHP+redis实现的购物车单例类示例
2019/02/02 PHP
超棒的javascript页面顶部卷动广告效果
2007/12/01 Javascript
基于jQuery的message插件实现右下角弹出消息框
2011/01/11 Javascript
jQuery Mobile的loading对话框显示/隐藏方法分享
2013/11/26 Javascript
JQuery中使用on方法绑定hover事件实例
2014/12/09 Javascript
wangEditor编辑器失去焦点后仍然可以在原位置插入图片分析
2015/05/06 Javascript
JavaScript小技巧整理篇(非常全)
2016/01/26 Javascript
巧方法 JavaScript获取超链接的绝对URL地址
2016/06/14 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
2016/12/29 Javascript
AngularJS中的promise用法分析
2017/05/19 Javascript
老生常谈ES6中的类
2017/07/31 Javascript
Vue.js进行查询操作的实例详解
2017/08/25 Javascript
Angular2的管道Pipe的使用方法
2017/11/07 Javascript
在react-router4中进行代码拆分的方法(基于webpack)
2018/03/08 Javascript
解决一个微信号同时支持多个环境网页授权问题
2019/08/07 Javascript
24个ES6方法解决JS实际开发问题(小结)
2020/05/31 Javascript
Python中实现对list做减法操作介绍
2015/01/09 Python
Python极简代码实现杨辉三角示例代码
2016/11/15 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
Python 如何优雅的将数字转化为时间格式的方法
2019/09/26 Python
简单了解python字符串前面加r,u的含义
2019/12/26 Python
详解HTML5中垂直上下居中的解决方案
2017/12/20 HTML / CSS
英国第一豪华护肤品牌:Elemis
2017/10/12 全球购物
经济实惠的名牌太阳镜和眼镜:Privé Revaux
2021/02/07 全球购物
Cynthia Rowley官网:全球领先的生活方式品牌
2020/10/27 全球购物
公司保密承诺书
2014/03/27 职场文书
群众路线教育党课主持词
2014/04/01 职场文书
岗位明星事迹材料
2014/05/18 职场文书
开学典礼策划方案
2014/05/28 职场文书
故宫英文导游词
2015/01/31 职场文书
邀请书模板
2015/02/02 职场文书
Python答题卡识别并给出分数的实现代码
2021/06/22 Python
使用 Apache Dubbo 实现远程通信(微服务架构)
2022/02/12 Servers