Vue数据驱动模拟实现3

 更新时间:2017年01月11日 09:24:35   作者:猴子  
这篇文章主要为大家详细介绍了Vue数据驱动模拟实现,教大家如何在某个对象中,新增某个属性,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一、前言

在"模拟Vue之数据驱动2"中,我们实现了个Observer构造函数,通过它可以达到监听已有数据data中的所有属性。

但,倘若我们想在某个对象中,新增某个属性呢?

如下:

那么岂不是,新增的infor属性,以及它的对象属性,没有得到监听。

此时,应该怎么处理呢?

通过走读Vue源码,发现他是采用另增属性方法$set实现的。

就是说,如果我们采用常规方法为对象增加属性(如上),我们没法得知并监控它,所以,我们为每个对象扩展一个$set方法,用于另增属性使用,即可,如下:

data.user.$set('infor', {msg: 'happy'});

好了,下面,我们就一同实现这个$set方法吧。

二、$set方法实现

首先,我们得创建一个恒定extendObj对象,用于将$set方法绑定在其中。

你可能会想,为什么我们需要一个extendObj对象呢?直接将$set函数赋值给每个需要监听的对象不就完了么?

是的,这样也可以,但是随着需求增长,倘若我们又想为每个监听对象扩展其他方法呢?难道又要去Observer里面为对象,一一赋值?

so,创建恒定extendObj对象,如下:

const extendObj = {};

因为,我们将$set绑定到extendObj中,且让$set为不可枚举型,所以会用到Object.defineProperty,固将其提取出来,作为一个方法如下:

function proxyObject(obj, key, val, enume){
  Object.defineProperty(obj, key, {
    value: val,
    enumerable: !!enume,
    writable: true,
    configurable: true
  });  
};

接下来,就是实现$set方法了,整体结构如下:

proxyObject(extendObj, '$set', function(key, val){
  //this指向extendObj
  if(this.hasOwnProperty(key)){
    return;
  }else{
    /*
     TODO:在extendObj中监听key属性,
     且,若key属性值为对象,再次监听key属性值
    */     
  }  
});

看到上面的TODO注释,是否似曾相识,不就是是在“模拟Vue之数据驱动2”遇见过的嘛,通过Observer.prototype.convert监听key属性,通过new Observer再次监听key属性值不就完啦。

的确,但是一旦这样做了,不就和上面我们提到的“直接将$set赋予监听对象”问题一样嘛,耦合性太大,且随着需求上涨,不易维护。

固而,在此需要一点小技巧:在observer模块中为每个监听对象赋予一个$Observer属性,其值指向Observer自身实例,如下:

//observer.js
p.walk = function(data){
  let keys = Object.keys(data);
  keys.forEach( key => {
    let val = data[key];
    if(typeof val === 'object'){
      new Observer(val);
    }
    this.convert(key, val);
  });
  //$Observer属性指向Observer自身实例
  data.$Observer = this;
}
//新增一个observe方法
p.observe = function(data){
  if(typeof data === 'object'){
    new Observer(data);  
  }  
}

好了,这样之后,得$set整体实现如下:

proxyObject(extendObj, '$set', function(key, val){
  if(this.hasOwnProperty(key)){
    return;
  }else{
    proxyObject(this, key, val, true);
    let ob = this.$Observer;
    ob.observe(val);
    ob.convert(key, val);  
  }  
});

到此,一个简单的$set方法构建完毕。

在上面我们提到,之所以需要一个恒定extendObj对象,是为了更好的代码管理。且,到目前为止,需要监听的对象上并没有扩展$set方法呢,所以,下面的事情就是为了达到以上效果,如下:

//observer.js
function Observer(data){
  if(!(this instanceof Observer)){
    return new Observer(data);
  }
  //将监听对象的隐指针指向我们的extendObj对象
  data.__proto__ = extendObj;
  this.data = data;
  this.walk(data);  
}

好了,一切完毕,接下来就测试下吧:

<script src="./extendObj.js"></script>
<script src="./observer.js"></script>
<script>
  let data = {
    user: {
      name: 'Monkey',
      age: 24
    },
    lover: {
      name: 'Dorie',
      age: 23
    }
  };
  Observer(data);
</script>

效果如下:

Perfect,完整代码见github

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Ant Design Vue日期组件的时间限制方式

    Ant Design Vue日期组件的时间限制方式

    这篇文章主要介绍了Ant Design Vue日期组件的时间限制方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能

    使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能

    在网站中普遍会遇到这样的需求,路由跳转前做一些验证,比如登录验证(未登录去登录页)。下面脚本之家小编给大家带来了使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能,感兴趣的朋友一起看看吧
    2018-03-03
  • Element el-table 表格使用详解

    Element el-table 表格使用详解

    我们的数据存储到数据库,不就是以表格的形式存在吗,所以在界面上显示、操作,使用表格来处理也是非常合理的,这篇文章给大家介绍Element el-table 表格使用方法,感兴趣的朋友一起看看吧
    2024-03-03
  • Vue精简版风格指南(推荐)

    Vue精简版风格指南(推荐)

    这篇文章主要介绍了Vue精简版风格指南的相关资料,包括组件名称,指令及特征,需要的朋友可以参考下
    2018-01-01
  • Vue实现图片与文字混输效果

    Vue实现图片与文字混输效果

    用多了 JQuery ,习惯了使用JQuery的API操作 DOM ,几乎忘记了原生JS对DOM操作,今天在项目中遇到了文字和图片混输的情况,小编给大家分享Vue实现图片与文字混输效果,感兴趣的朋友一起看看吧
    2019-12-12
  • vue.js实现用户评论、登录、注册、及修改信息功能

    vue.js实现用户评论、登录、注册、及修改信息功能

    这篇文章主要为大家详细介绍了vue.js实现用户评论、登录、注册、及修改信息功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • Vue3+Element+Ts实现表单的基础搜索重置等功能

    Vue3+Element+Ts实现表单的基础搜索重置等功能

    本文主要介绍了Vue3+Element+Ts实现表单的基础搜索重置等功能,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • 在vue组件中使用axios的方法

    在vue组件中使用axios的方法

    下面小编就为大家分享一篇在vue组件中使用axios的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • Vue 打包上线后的缓存问题解决

    Vue 打包上线后的缓存问题解决

    在使用vue脚手架搭建前端工程时,经常会遇到打包上线后的缓存问题,许多开发者会直接在index.html中加入类似以下代码来解决缓存问题,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2023-11-11
  • 详解Vue3中如何使用动态组件

    详解Vue3中如何使用动态组件

    在 Vue 3 中,动态组件是一种允许在运行时动态切换组件的机制,本文主要为大家详细介绍了动态组件在Vue3中的具体使用,感兴趣的小伙伴可以了解下
    2024-01-01

最新评论