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中的变量是传值还是传址的?
Apr 19 Javascript
JavaScript入门之事件、cookie、定时等
Oct 21 Javascript
js实现目录定位正文示例
Nov 14 Javascript
JS对文本框值的判断示例
Mar 10 Javascript
jQuery实现图片轮播特效代码分享
Sep 15 Javascript
jquery 遍历数组 each 方法详解
May 25 Javascript
JS弹出新窗口被拦截的解决方法
Aug 09 Javascript
vue-router实现webApp切换页面动画效果代码
May 25 Javascript
JavaScript之json_动力节点Java学院整理
Jun 29 Javascript
vue轮播图插件vue-concise-slider的使用
Mar 13 Javascript
如何把vuejs打包出来的文件整合到springboot里
Jul 26 Javascript
vue-router权限控制(简单方式)
Oct 29 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
PHP包含文件函数include、include_once、require、require_once区别总结
2014/04/05 PHP
JQuery Ajax 跨域访问的解决方案
2010/03/12 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
2013/06/06 Javascript
JS中数组Array的用法示例介绍
2014/02/20 Javascript
Node.js 服务器端应用开发框架 -- Hapi.js
2014/07/29 Javascript
JavaScript的Number对象的toString()方法
2015/12/18 Javascript
在页面中输出当前客户端时间javascript实例代码
2016/03/02 Javascript
JS表格组件神器bootstrap table详解(强化版)
2016/05/26 Javascript
JS 根据子网掩码,网关计算出所有IP地址范围示例
2020/04/23 Javascript
JQuery学习总结【二】
2016/12/01 Javascript
AngularJS路由实现页面跳转实例
2017/03/03 Javascript
xmlplus组件设计系列之文本框(TextBox)(3)
2017/05/03 Javascript
基于jquery实现多级菜单效果
2017/07/25 jQuery
详解A标签中href=""的几种用法
2017/08/20 Javascript
Vue+Vux项目实践完整代码
2017/11/30 Javascript
Vue的土著指令和自定义指令实例详解
2018/02/04 Javascript
jQuery UI实现动画效果代码分享
2018/08/19 jQuery
JavaScript偏函数与柯里化实例详解
2019/03/27 Javascript
使用vue实现各类弹出框组件
2019/07/03 Javascript
微信小程序实现倒计时功能
2020/11/19 Javascript
python通过urllib2获取带有中文参数url内容的方法
2015/03/13 Python
Python操作MongoDB数据库PyMongo库使用方法
2015/04/27 Python
Python中用于转换字母为小写的lower()方法使用简介
2015/05/19 Python
对numpy中二进制格式的数据存储与读取方法详解
2018/11/01 Python
在Python中居然可以定义两个同名通参数的函数
2019/01/31 Python
python实现nao机器人身体躯干和腿部动作操作
2019/04/29 Python
Django框架视图介绍与使用详解
2019/07/18 Python
Python实现字符串中某个字母的替代功能
2019/10/21 Python
Anaconda+spyder+pycharm的pytorch配置详解(GPU)
2020/10/18 Python
巴西服装和鞋子购物网站:Marisa
2018/10/25 全球购物
linux面试题参考答案(4)
2013/01/28 面试题
计算机应用专业推荐信
2013/11/13 职场文书
“向国旗敬礼”主题班会活动设计方案
2014/09/27 职场文书
小班下学期幼儿评语
2014/12/30 职场文书
党支部创先争优公开承诺书
2015/04/30 职场文书