博客
关于我
vue简版源码 Observer
阅读量:331 次
发布时间:2019-03-04

本文共 2369 字,大约阅读时间需要 7 分钟。

vue简版源码 Observer

<script src="./mvvm-master/js/observer.js"></script>  // observer 观察者

Observer

function Observer(data) {       //在Observer实例上暂存data    this.data = data;    this.walk(data);}Observer.prototype = {       walk: function(data) {           var me = this;        //对data里所有的属性名进行遍历        Object.keys(data).forEach(function(key) {               me.convert(key, data[key]);        });    },    convert: function(key, val) {           //为每个属性增加响应式        this.defineReactive(this.data, key, val);    },    defineReactive: function(data, key, val) {           //为data中所有层次的属性都创建一个dep实例        var dep = new Dep();        //递归遍历data中所有层次的属性        var childObj = observe(val);        //为原有属性新增get和set方法(数据劫持)        Object.defineProperty(data, key, {               enumerable: true, // 可枚举            configurable: false, // 不能再define            get: function() {                   //判断当前Dep.target的watcher是否存在                if (Dep.target) {   //当模版初始化的时候会赋值watcher实例到target上                    //调用dep的depend方法                    dep.depend();                }                return val;            },            set: function(newVal) {                   if (newVal === val) {                       return;                }                val = newVal;                // 新的值是object的话,进行监听                childObj = observe(newVal);                // 通知订阅者                dep.notify();            }        });    }};function observe(value, vm) {       //判断value是否存在或者value的数据类型是否为object(递归的终止条件)    if (!value || typeof value !== 'object') {           return;    }    return new Observer(value);};var uid = 0;function Dep() {       //没创建一个dep都会给这个dep增加一个独立的标识    this.id = uid++;    this.subs = []; //watcher}Dep.prototype = {       addSub: function(sub) {           this.subs.push(sub);    },    //调用watcher实例的addDep方法    depend: function() {           //Dep.target此时是watcher的实例        //this此时是当前dep的实例        Dep.target.addDep(this);    },    removeSub: function(sub) {           var index = this.subs.indexOf(sub);        if (index != -1) {               this.subs.splice(index, 1);        }    },    //通知所有的watcher    notify: function() {           // beforeUpdate        //遍历subs中所有的watcher的实例        this.subs.forEach(function(sub) {               // 每一个watcher的实例调用update方法            sub.update();        });        // updated    }};Dep.target = null;

转载地址:http://vnke.baihongyu.com/

你可能感兴趣的文章
【故障公告】极验验证码故障造成无法登录与注册
查看>>
上周热点回顾(6.25-7.1)
查看>>
【故障公告】10:30-10:45 左右 docker swarm 集群节点问题引发故障
查看>>
工作半年的思考
查看>>
不可思议的纯 CSS 滚动进度条效果
查看>>
【CSS进阶】伪元素的妙用--单标签之美
查看>>
开始CN的生活
查看>>
惊闻NBC在奥运后放弃使用Silverlight
查看>>
IE下尚未实现错误的原因
查看>>
Kubernetes 学习系列文章
查看>>
创建自己的Docker基础镜像
查看>>
使用Jenkins来实现内部的持续集成流程(上)
查看>>
HTTP 协议图解
查看>>
Python 简明教程 --- 20,Python 类中的属性与方法
查看>>
Python 简明教程 --- 21,Python 继承与多态
查看>>
KNN 算法-理论篇-如何给电影进行分类
查看>>
Spring Cloud第九篇 | 分布式服务跟踪Sleuth
查看>>
CODING 敏捷实战系列课第三讲:可视化业务分析
查看>>
使用 CODING DevOps 全自动部署 Hexo 到 K8S 集群
查看>>
工作动态尽在掌握 - 使用 CODING 度量团队效能
查看>>