>[warning]訂閱者&觀察者定義
****
1. 思路:
(1): 新建訂閱者Dep, 在屬性劫持時, 往Dep中給每個屬性綁定一個Watcher對象
(2): 當屬性觸發set方法時, 調用Dep里所有的watcher執行

2. 代碼如下:
~~~
<script>
function myObjectDefinePropery(data, key, val) {
if (val && typeof val === 'object') {
observe(val);
return;
}
// 7. 實例化Dep類對象
let dep = new Dep();
Object.defineProperty(data, key, {
get: function() {
// 8. (Dep.target 指的是Watcher實例對象, 如果有, 則添加到訂閱類中)
if (Dep.target){
// 9. 添加Watcher到訂閱類中
dep.addSub(Dep.target);
}
return val;
},
set: function(newVal) {
// 判斷set時值一樣則退出
if (val === newVal){
return;
}
val = newVal;
// 10. 屬性發生變化, 通知訂閱者, 調用所有Wathcer執行對應方法
dep.notify();
}
});
}
function observe(data) {
Object.keys(data).forEach(function(key) {
myObjectDefinePropery(data, key, data[key]);
});
}
// 1. 新建訂閱類, 屬性改變, 觸發方法, 收集這些方法
function Dep () {
// 用于放置每個屬性變化時應該執行的方法體
this.watcherArr = [];
}
Dep.prototype = {
// 2. 用于添加屬性改變對應執行的方法
addSub: function(watcher){
this.watcherArr.push(watcher);
},
// 3. 用于通知所有watcher, 讓watcher觀察者執行自己對應的方法體
notify: function(){
this.watcherArr.forEach(function(watcher){
// 4. 觀察者執行對應代碼, 可以跳轉到Watcher類的update方法查看
watcher.update();
})
}
};
// 5. 定義觀察類, 用于監視某些屬性
function Watcher(model, exp) {
// 用在Object.definePropery的get方法中, 用于保存當前觀察者對象
Dep.target = this;
// 給這個model綁定數據劫持
observe(model);
// 觸發Object.definePropery的get方法
model[exp];
}
// 6. 屬性被修改了, 觸發update方法
Watcher.prototype = {
update: function() {
console.log("屬性更新了");
}
};
// 11. 實例化觀察類, 讓它觀察這個對象
let model = {
userName: ""
};
new Watcher(model, "userName");
// 12. 修改屬性值, 看update方法里代碼是否執行
model.userName = "ok";
</script>
~~~
[當前頁源代碼](https://github.com/lidongxuwork126com/ldx_vue/tree/master/%E4%BB%BFVue%E6%BA%90%E7%A0%81)
那么如何模擬Vue類呢, 看下個文章
- web前端
- CSS問題
- 布局
- 雙飛翼布局_flex方式
- 雙飛翼布局_margin方式
- 圣杯布局_flex方式
- 圣杯布局_margin方式
- 子元素居中問題
- 彈性布局
- 概念_
- 標準模式與混雜模式
- 各種FC
- line-height
- vertical-align
- CSS3新特性
- 效果
- div添加箭頭
- CSS繪制三角形
- JavaScript
- 兼容
- 事件相關
- 原理
- Ajax原理
- 繼承原理
- 原型鏈繼承
- 組合繼承
- 寄生組合繼承
- 數據綁定
- 1單向數據綁定m到c到v
- 2偽雙向數據綁定
- 3雙向數據綁定
- socket.io
- 運行時
- this指向
- 0.1+0.2問題
- 對象/數組-深拷貝&淺拷貝
- 事件循環
- typeof
- instanceof
- 概念
- 閉包
- 回調函數
- Promise
- 原生對象
- Attribute和property區別
- 防抖函數
- 節流函數
- 語言類型
- Vue
- Vue優缺點
- 仿Vue源碼
- 1數據綁定_Observe
- 2數據綁定_訂閱者&觀察者定義
- 3數據綁定_Vue類實現
- 4數據綁定_Vue訪問data更改
- 5DOM編譯_Compile_雙大括號模板講解
- 6DOM編譯_v-model講解
- 7DOM編譯_v-on:事件綁定講解
- 項目總結
- 使用Svg圖標
- vueCli環境_真機測試
- vueCli集成環信SDK
- 父子組件雙向綁定
- React
- React優缺點
- 我的組件庫
- Vue的組件庫
- 環信_聊天組件
- 面試題
- HTML_分類
- CSS_分類
- JavaScript_分類
- VueJS_分類
- ReactJS_分類
- AngularJS_分類
- 瀏覽器端
- 筆試題
- CSS
- 特殊布局
- JavaScript_
- 經典_宏任務_微任務
- 瀏覽器問題
- CORS
- web服務器
- Apache
- 開啟跨域
- Nginx
- 常用命令
- 正向代理
- 反向代理
- 負載均衡
- mac安裝Nginx
- 配置80端口
- 算法
- 冒泡排序
- 選擇排序
- 合并對象_排序
- 楊輝三角
- 紅黑樹
- 計算機基礎
- 網絡相關
- OSI七層模型
- http協議
- http工作原理
- https協議
- GET和POST區別
- hosts文件
- php相關
- session機制
- Linux
- 阿里云服務器
- linux使用Mysql
- 安裝mysql
- 導入.sql文件
- 遠程連接mysql
- linux使用xampp
- 安裝Xampp
- 配置web訪問
- 域名綁定服務器
- linux搭建git服務器_apache下
- 代碼管理
- 什么是git
- 命令行_使用git
- .gitignore文件講解
- 軟件
- VSCode的安裝
- 理財
- 基金
- 攝影