一、前言
在随笔“模拟Vue之数据驱动1”结尾处,我们说到如果监听的属性是个对象呢?那么这个对象中的其他属性岂不就是监听不了了吗?
如下:
倘若user中的name、age属性变化,如何知道它们变化了呢?
今儿,就来解决这一问题。
通过走读Vue源码,发现他是利用Observer构造函数为每个对象创建一个Observer对象,来监听数据的,如果数据中的属性又是一个对象,那么就又通过Observer来监听嘛。
其实,核心思想就是树的先序遍历(关于树,可参考here)。如我们将上述Demo中的data数据,图形化一下,就更加明白了,如下:
好了,理清了大体思路,下面我们就一起来创建一个Observer吧。
二、Observer构造
Observer整体结构如下:
function Observer(data){ //如若this不是Observer对象,即创建一个 if(!(this instanceof Observer)){ return new Observer(data); } this.data = data; this.walk(data); } let p = Observer.prototype = Object.create(null); p.walk = function(data){ /* TODO:监听data数据中的所有属性, 并查看data中属性值是否为对象, 若为对象,就创建一个Observer实例 */ } p.convert = function(key, val){ //TODO:通过Object.defineProperty监听数据 }
好了,下面,我们一起来完成walk以及convert方法吧。
-walk-
首先,我们在walk方法中实现对data对象中的所有属性监听,如下:
p.walk = function(data){ let keys = Object.keys(data); keys.forEach( key => { let val = data[key]; this.convert(key, val); }); }
且,由于属性中可能又会是一个对象,那么,我们就有必要监听它们。
怎么办呢?
如果是个对象,再次利用Observer构造函数,处理它不就完了么。
如下:
p.walk = function(data){ let keys = Object.keys(data); keys.forEach( key => { let val = data[key]; //如果val为对象,则交给Observer处理 if(typeof val === 'object'){ Observer(val); } this.convert(key, val); }); }
你可能会有这样的疑问,如果直接利用Observer处理对象,那么不就与父对象失去关联了么?
然而并没有,因为JavaScript对于对象是指向地址关系,所以怎么会失去关联呢。
-convert-
对于convert方法,就比较简单了,一如既往就是利用Object.defineProperty监听数据,如下:
p.convert = function(key, val){ Object.defineProperty(this.data, key, { get: ()=>{ console.log('访问了'+key+' 值为'+val); return val; }, set: (newVal)=>{ console.log('设置了'+key+' 值为'+newVal); if(newVal !== val){ val = newVal; } } }); }
好了,到此,一个简单的Observer就构造完成,下面我们就来测试下,是否成功监听了每个属性。
Vue,数据驱动
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。