一、前言

在"模拟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。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# Vue
# 数据驱动
# Vue数据驱动表单渲染
# 轻松搞定form表单
# 浅谈vuejs实现数据驱动视图原理
# 详解VueJS 数据驱动和依赖追踪分析
# Vue数据驱动模拟实现5
# Vue数据驱动模拟实现4
# Vue数据驱动模拟实现2
# Vue数据驱动模拟实现1
# 详解Vue数据驱动原理
# 好了
# 不就
# 绑定
# 是在
# 他是
# 在此
# 已有
# 将其
# 太大
# 这样做
# 又要
# 作为一个
# 它可以
# 在上面
# 到此
# 岂不是
# 似曾相识
# 创建一个
# 小技巧
# 值为
相关文章:
如何快速生成专业多端适配建站电话?
江苏网站制作公司有哪些,江苏书法考级官方网站?
如何通过虚拟主机空间快速建站?
测试制作网站有哪些,测试性取向的权威测试或者网站?
网站制作的方法有哪些,如何将自己制作的网站发布到网上?
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
建站10G流量真的够用吗?如何应对访问高峰?
小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?
网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?
高防服务器租用指南:配置选择与快速部署攻略
红河网站制作公司,红河事业单位身份证如何上传?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
制作网站的基本流程,设计网站的软件是什么?
天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?
武清网站制作公司,天津武清个人营业执照注销查询系统网站?
建站OpenVZ教程与优化策略:配置指南与性能提升
实例解析angularjs的filter过滤器
h5网站制作工具有哪些,h5页面制作工具有哪些?
可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?
如何选择香港主机高效搭建外贸独立站?
无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?
上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?
seo网站制作优化,网站SEO优化步骤有哪些?
如何确认建站备案号应放置的具体位置?
建站之星微信建站一键生成小程序+多端营销系统
如何通过可视化优化提升建站效果?
婚礼视频制作网站,学习*后期制作的网站有哪些?
如何通过FTP服务器快速搭建网站?
建站主机系统SEO优化与智能配置核心关键词操作指南
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
电商网站制作公司有哪些,1688网是什么意思?
在线制作视频网站免费,都有哪些好的动漫网站?
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
如何通过VPS建站无需域名直接访问?
整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?
平台云上自助建站如何快速打造专业网站?
建站之家VIP精选网站模板与SEO优化教程整合指南
建站之星客服服务时间及联系方式如何?
如何在七牛云存储上搭建网站并设置自定义域名?
如何选择高性价比服务器搭建个人网站?
代刷网站制作软件,别人代刷火车票靠谱吗?
七夕网站制作视频,七夕大促活动怎么报名?
Python如何创建带属性的XML节点
常州自助建站:操作简便模板丰富,企业个人快速搭建网站
网站制作难吗安全吗,做一个网站需要多久时间?
如何高效配置IIS服务器搭建网站?
如何在服务器上三步完成建站并提升流量?
一键网站制作软件,义乌购一件代发流程?
如何用已有域名快速搭建网站?
如何有效防御Web建站篡改攻击?
*请认真填写需求信息,我们会在24小时内与您取得联系。