一、vue.js
1 import reactive from "./reactive"; 2 import Watcher from "./Watcher"; 3 import computed from "./computed"; 4 import watch from "./watch"; 5 6 export { reactive, Watcher, computed, watch };
二、reactive.js
1 import { isObject } from "./utils"; 2 import Dep from "./Dep"; 3 4 export default function reactive(data) { 5 if (isObject(data)) { 6 Object.keys(data).forEach(function (key) { 7 defineReactive(data, key); 8 }); 9 } 10 return data; 11 } 12 function defineReactive(data, key) { 13 let val = data[key]; 14 const dep = new Dep(); 15 16 Object.defineProperty(data, key, { 17 get() { 18 dep.depend(); 19 return val; 20 }, 21 set(newVal) { 22 val = newVal; 23 dep.notify(); 24 }, 25 }); 26 27 if (isObject(val)) { 28 reactive(val); 29 } 30 }
三、utils.js
1 export function isObject(val) { 2 return typeof val == "object"; 3 }
四、Dep.js
1 export default class Dep { 2 constructor() { 3 this.deps = new Set(); 4 } 5 depend() { 6 if (Dep.target) { 7 this.deps.add(Dep.target); 8 } 9 } 10 notify() { 11 this.deps.forEach(function (watcher) { 12 watcher.update(); 13 }); 14 } 15 } 16 Dep.target = null; 17 18 const targetStack = []; 19 20 export function pushTarget(_target) { 21 if (Dep.target) { 22 targetStack.push(Dep.target); 23 } 24 Dep.target = _target; 25 } 26 27 export function popTarget() { 28 if (targetStack.length) { 29 Dep.target = targetStack.pop(); 30 } else { 31 Dep.target = null; 32 } 33 }
五、Watcher.js
1 import Dep, { pushTarget, popTarget } from "./Dep"; 2 3 export default class Watcher { 4 constructor(getter, options = {}) { 5 const { computed, watch, callback } = options; 6 7 this.getter = getter; 8 this.computed = computed; 9 this.watch = watch; 10 this.callback = callback; 11 this.value = ""; 12 13 if (computed) { 14 this.dep = new Dep(); 15 } else { 16 this.get(); 17 } 18 } 19 depend() { 20 this.dep.depend(); 21 } 22 get() { 23 pushTarget(this); 24 const value = this.getter(); 25 popTarget(); 26 if (this.watch) { 27 this.value = value; 28 } 29 return value; 30 } 31 update() { 32 if (this.computed) { 33 this.get(); 34 this.dep.notify(); 35 } else if (this.watch) { 36 const oldVal = this.value; 37 this.get(); 38 this.callback(this.value, oldVal); 39 } else { 40 this.get(); 41 } 42 } 43 }
六、computed.js
1 import Watcher from "./Watcher"; 2 3 export default function computed(getter) { 4 let def = {}; 5 const watcher = new Watcher(getter, { computed: true }); 6 Object.defineProperty(def, "value", { 7 get() { 8 watcher.depend(); 9 return watcher.get(); 10 }, 11 }); 12 return def; 13 }
七、watch.js
1 import Watcher from "./Watcher"; 2 3 export default function watch(getter, callback) { 4 new Watcher(getter, { watch: true, callback }); 5 }
八、index.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 7 <link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" /> 8 <title>Document</title> 9 </head> 10 <body> 11 <div id="app"> 12 <div class="watcher"> 13 watcher view: 14 <span class="text"></span> 15 <button class="change">change</button> 16 </div> 17 <div class="computed"> 18 computed view: 19 <span class="text"></span> 20 <button class="change">change</button> 21 </div> 22 </div> 23 <script type="module" src="./main.js"></script> 24 </body> 25 </html>
九、server.js
1 const http = require("http"), 2 fs = require("fs"); 3 4 const server = new http.Server(); 5 6 server.on("request", (req, res) => { 7 const url = req.url; 8 const suffix = url.match(/(?<=\.)\w*$/)?.[0] || "js"; // 匹配文件格式 9 const fileName = url.match(/.*(?=\.\w*$)|\/?\w*/)[0]; // 匹配文件名 10 let mime = ""; 11 switch (suffix) { 12 case "html": 13 mime = "text/html"; 14 break; 15 case "ico": 16 mime = "image/x-icon"; 17 break; 18 default: 19 mime = "text/javascript"; 20 } 21 22 fs.readFile(`.${fileName}.${suffix}`, (err, data) => { 23 res.writeHead(200, { 24 "Content-Type": mime, 25 }); 26 res.write(data); 27 res.end(); 28 }); 29 }); 30 31 server.listen(80);
十、启动
node server.js ,浏览器访问:http://localhost/index.html
标签:const,computed,Dep,watch,Watcher,reactive,target From: https://www.cnblogs.com/aurora-power/p/16898141.html