全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

源码分析Vue.js的监听实现教程

前言

相信一说到监听,当然就离不了设计模式中鼎鼎大名的观察者模式。举个例子,你家后院着火了,可一定要等到烟雾很大火光很亮你才能发现啊,可是当你安装了一个火灾预警器,当发生火灾就立马能够通知到你了。这就是一个典型的观察者模式。当然也还有一些其他变种,比如发布/订阅(publish/subscribe)模式。

我们知道如果要将数据和视图关联起来,在数据变更的时候,同步视图,同理视图变更,数据也发生变化。vue.js是怎么实现这个的呢?下面我们来揭开它的神秘面纱。

demo:

<script src="../vue.js"> </script>
<div id="app">
 <p>
 {{ message }}
 </p>
 <input v-model="message">
</div>
<script type="text/javascript">
new Vue({
 el: '#app',
 data: {
 message: 'Hello Vue.js!'
 }
});
</script>




set: function reactiveSetter(newVal) {
 var value = getter ? getter.call(obj) : val;
 if (newVal === value) {
 return;
 }
 if (setter) {
 setter.call(obj, newVal);
 } else {
 val = newVal;
 }
 childOb = observe(newVal);
 dep.notify();
}

这段代码出现在解析data属性的时候,即调用Object.defineProperty方法配置data的属性。一旦属性发生变化,就notify发送广播。

Dep.prototype.notify = function () {
 // stablize the subscriber list first
 var subs = toArray(this.subs);
 for (var i = 0, l = subs.length; i < l; i++) {
 subs[i].update();
 }
};

notify 最终是周知subscribe(订阅者)更新,那么上面的数据变更就是发布者。 subscribe是Watcher这个类的实例化对象,在实例化的时候,会传入回调函数来执行update,vue弄了一个队列来执行watcher的更新函数,具体可参考源码。

Watcher.prototype.run = function () {
 ……
 if (value !== this.value || (isObject(value) || this.deep) && !this.shallow) {
 ……
 } else {
 this.cb.call(this.vm, value, oldValue);
 }
 }
 this.queued = this.shallow = false;
 }
 };

在Directive(指令)class中实例化了Watcher,_update函数负责来更新

var watcher = this._watcher = new Watcher(this.vm, this.expression, this._update, // callback
 {
 filters: this.filters,
 twoWay: this.twoWay,
 deep: this.deep,
 preProcess: preProcess,
 postProcess: postProcess,
 scope: this._scope
 });

在解析模板的时候会解析Directive,然后绑定,实例化watcher,这样模板-data就关联在一起了。

图片描述

观察者模式

林林总总的mvc或者mvvm框架基本也都是利用了观察者模式,这个也非常有用,尤其在复杂的系统之中。

利用观察者模式,在典型的ajax应用中,回调的处理逻辑可以不跟请求耦合在一块,这样逻辑上也会更加清晰。如下是一个简单的发布/订阅模式的实现

var PubSub = {};
(function (q) {
 var topics = {}, subUid = -1;
 q.publish = function (topic) {
 if(!topics[topic]){
  return false;
 }

 var subscribers = topics[topic],
  len = subscribers ? subscribers.length : 0;

 while(len--){
  var args = Array.prototype.slice.call(arguments, 1);
  args.unshift(topic);
  subscribers[len].callback.apply(this, args);
 }
 return this;
 };

 q.subscribe = function (topic, callback) {
 if(!topics[topic]){
  topics[topic] = [];
 }

 var subuid = (++subUid).toString();

 topics[topic].push({
  token: subuid,
  callback: callback
 });

 return subuid;
 };

 q.unsubscribe = function (subid) {
 for(var k in topics){
  if(topics[k]){
  for(var i = 0, j = topics[k].length; i < j; i++){
   if(topics[k][i].token === subid){
   topics[k].splice(i, 1);
   return subid;
   }
  }
  }
 }
 return this;
 };
})(PubSub);

这就是一个简单的订阅发布系统,每注册一个订阅者,其实就是将其回调处理的callback保存在一个字典对象的数组中,字典对象的key值可以随意定义,只要与发布时的key对应起来就好。

怎么使用呢?

<script>
var messageLogger = function(){
 console.log(JSON.stringify(arguments));
 };

var subscription = PubSub.subscribe('/newMessage', messageLogger);
// {"0":"/newMessage","1":"hello world"}
PubSub.publish('/newMessage', 'hello world');

// {"0":"/newMessage","1":["test","a","b","c"]}
PubSub.publish('/newMessage', ['test', 'a', 'b', 'c']);

// {"0":"/newMessage","1":{"sender":"hello world","body":"hey man"}}
PubSub.publish('/newMessage', {
 sender: 'hello world',
 body: 'hey man'
});

PubSub.unsubscribe(subscription);

PubSub.publish('/newMessage', ['test', 'a', 'b', 'c'], 1);
</script>

最后一个将不会打印出来,因为已经取消订阅了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# vue.js  # 监听  # vue  # js  # 监听数据变化  # 监听事件  # 用Vue.js实现监听属性的变化  # Vue.JS入门教程之事件监听  # 详解使用vue-router进行页面切换时滚动条位置与滚动监听事件  # vue.js 1.x与2.0中js实时监听input值的变化  # 详解Vue监听数据变化原理  # vue监听滚动事件实现滚动监听  # Vue.js实战之通过监听滚动事件实现动态锚点  # Vue监听数组变化源码解析  # vuejs2.0实现分页组件使用$emit进行事件监听数据传递的方法  # Vue监听数据对象变化源码  # 是一个  # 回调  # 这就  # 周知  # 都是  # 也会  # 鼎鼎大名  # 出现在  # 是怎么  # 就好  # 当你  # 林林总总  # 说到  # 将其  # 这段  # 你了  # 要将  # 这篇文章  # 谢谢大家  # 发布系统 


相关文章: 企业网站制作公司网页,推荐几家专业的天津网站制作公司?  免费ppt制作网站,有没有值得推荐的免费PPT网站?  ,石家庄四十八中学官网?  太原网站制作公司有哪些,网约车营运证查询官网?  如何快速搭建高效简练网站?  如何用搬瓦工VPS快速搭建个人网站?  在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?  如何配置WinSCP新建站点的密钥验证步骤?  交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?  如何规划企业建站流程的关键步骤?  建站主机是否等同于虚拟主机?  建站之星后台搭建步骤解析:模板选择与产品管理实操指南  青岛网站建设如何选择本地服务器?  ,sp开头的版面叫什么?  C++如何将C风格字符串(char*)转换为std::string?(代码示例)  香港服务器网站推广:SEO优化与外贸独立站搭建策略  天津个人网站制作公司,天津网约车驾驶员从业资格证官网?  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  如何在云主机上快速搭建多站点网站?  大学网站设计制作软件有哪些,如何将网站制作成自己app?  制作营销网站公司,淘特是干什么用的?  如何安全更换建站之星模板并保留数据?  如何选择高效便捷的WAP商城建站系统?  建站主机服务器选购指南:轻量应用与VPS配置解析  广东专业制作网站有哪些,广东省能源集团有限公司官网?  网站制作的方法有哪些,如何将自己制作的网站发布到网上?  如何挑选优质建站一级代理提升网站排名?  网站制作说明怎么写,简述网页设计的流程并说明原因?  高防服务器租用如何选择配置与防御等级?  网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?  如何在IIS服务器上快速部署高效网站?  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  ,怎么用自己头像做动态表情包?  如何在香港免费服务器上快速搭建网站?  网站企业制作流程,用什么语言做企业网站比较好?  如何在IIS7上新建站点并设置安全权限?  网站制作哪家好,cc、.co、.cm哪个域名更适合做网站?  c# 在ASP.NET Core中管理和取消后台任务  完全自定义免费建站平台:主题模板在线生成一站式服务  如何在Golang中使用replace替换模块_指定本地或远程路径  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  PHP正则匹配日期和时间(时间戳转换)的实例代码  ui设计制作网站有哪些,手机UI设计网址吗?  ,交易猫的商品怎么发布到网站上去?  网站制作新手教程,新手建设一个网站需要注意些什么?  太平洋网站制作公司,网络用语太平洋是什么意思?  如何在阿里云部署织梦网站?  Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解  深入理解Android中的xmlns:tools属性  常州企业建站如何选择最佳模板? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。