zoukankan      html  css  js  c++  java
  • Vue------发布订阅模式实现

    图解

    html

     1 <body>
     2   <script src="./Dvue.js"></script>
     3   <script>
     4     const app = new DVue({
     5       data: {
     6         test: "I am test",
     7         foo: {
     8           bar: "bar"
     9         }
    10       }
    11     })
    12 
    13     app.$data.test = "hello world!"
    14     // app.$data.foo.bar = "hello!"
    15   </script>
    16 </body>

    Dvue.js

     1 class DVue {
     2   constructor(options) {
     3     this.$options = options
     4 
     5     // 数据响应化
     6     this.$data = options.data
     7     this.observe(this.$data)
     8 
     9     // 模拟一下watcher创建
    10     // 激活get 并将依赖添加到deps数组上
    11     new Watcher()
    12     this.$data.test
    13     new Watcher()
    14     this.$data.foo.bar
    15   }
    16 
    17   observe(value) {
    18     // 判断value是否是对象    
    19     if (!value || typeof value !== 'object') {
    20       return
    21     }
    22     
    23     // 遍历该对象
    24     Object.keys(value).forEach(key => {
    25       this.defineReactive(value, key, value[key])
    26     })
    27   }
    28 
    29   // 数据响应化
    30   defineReactive(obj, key, val) {
    31     // 判断val内是否还可以继续调用(是否还有对象)
    32     this.observe(val) // 递归解决数据嵌套
    33 
    34     // 初始化dep
    35     const dep = new Dep()
    36 
    37     Object.defineProperty(obj, key, {
    38       get() {
    39         // 读取的时候 判断Dep.target是否有,如果有则调用addDep方法将Dep.target添加到deps数组上
    40         Dep.target && dep.addDep(Dep.target)
    41         return val
    42       },
    43       set(newVal) {
    44         if (newVal === val) {
    45           return;
    46         }
    47         val = newVal
    48         // console.log(`${key}属性更新了:${val}`)
    49         dep.notify() // 更新时候调用该方法
    50       }
    51     })
    52   }
    53 }
    54 
    55 
    56 // Dep: 用来管理Watcher
    57 class Dep {
    58   constructor() {
    59     // 这里存放若干依赖(watcher) |一个watcher对应一个属性
    60     this.deps = [];
    61   }
    62 
    63   // 添加依赖
    64   addDep (dep) {
    65     this.deps.push(dep)
    66   }
    67 
    68   // 通知方法
    69   notify() {
    70     this.deps.forEach(dep => dep.update())
    71   }
    72 }
    73 
    74 // Watcher
    75 class Watcher {
    76   constructor () {
    77     // 将当前watcher实例指定到Dep静态属性target上
    78     Dep.target = this   // 当前this就是Watcher对象
    79   }
    80 
    81   update() {
    82     console.log('属性更新了')
    83   }
    84 }
  • 相关阅读:
    多Web服务器之间共享Session的解决方案
    在WinForm中使用CacheDependency来监视文件
    使用WCF的一些问题
    IIS6.0配置注意
    匿名委托注册事件的触发
    关于datawindow does not have update capability
    EF自关联建模详解
    NHiberante3.2版注意
    EF做数据绑定时一些神奇问题
    EF 中不同会话上下文的对象,不能互设为对方的导航属性值
  • 原文地址:https://www.cnblogs.com/PasserByOne/p/12132649.html
Copyright © 2011-2022 走看看