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 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM