实现简易版的 Vue
2022/2/3 23:12:40
本文主要是介绍实现简易版的 Vue,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
class Vue { constructor(options) { this.$data = options.data; // 进行数据劫持 this.Observe(options.data); // 编译模版 this.Compile(options.el); } Observe(data) { if (!data || typeof data !== 'object') { return; } const dep = new Dep(); Object.keys(data).forEach(key => { let _that = this; let value = data[key]; this.Observe(value); Object.defineProperty(data, key, { enumerable: true, configurable: true, get() { // 收集依赖 Dep.target && dep.addSub(Dep.target); return value; }, set(newVal) { value = newVal; _that.Observe(newVal); dep.notify(); } }); }) } Compile(el) { // const vm = this.$el; this.$el = document.querySelector(el); const fragment = document.createDocumentFragment(); let childNode; while (childNode = this.$el.firstChild) { fragment.appendChild(childNode); } this.replace(fragment); this.$el.appendChild(fragment); } replace(node) { // 进行替换了 const regMustache = /\{\{\s*(\S+)\s*\}\}/; // 文本子节点, 就是最里层了 if (node.nodeType === 3) { const text = node.textContent; // console.log(text); const execResult = regMustache.exec(text); console.log(execResult); if (execResult) { const value = execResult[1].split('.').reduce((newObj, key) => newObj[key], this.$data); node.textContent = text.replace(regMustache, value); // 创建 watcher 实例 console.log(1111); new Watcher(this, execResult[1], (newValue) => { node.textContent = text.replace(regMustache, newValue); }); } return; } if (node.nodeType === 1 && node.tagName.toUpperCase() == 'INPUT') { const attrs = Array.from(node.attributes); const findResult = attrs.find(attr => attr.name === 'v-model'); if (findResult) { const expStr = findResult.value; const value = expStr.split('.').reduce((newObj, key) => newObj[key], this.$data); node.value = value; // 创建 watcher 实例 new Watcher(this, expStr, (newValue) => { node.value = newValue; }) node.addEventListener('input', (e) => { const keyArr = expStr.split('.'); const obj = keyArr.splice(0, keyArr.length - 1).reduce((newObj, key) => newObj[key], this.$data); obj[keyArr[keyArr.length - 1]] = e.target.value; }) } } // console.dir(node) node.childNodes.forEach(child => this.replace(child)); } } class Dep { constructor() { this.subs = []; } // 收集依赖 addSub(watcher) { this.subs.push(watcher); } // 通知 notify() { this.subs.forEach(watcher => watcher.update()); } } class Watcher { constructor(vm, key, callback) { this.vm = vm; this.key = key; this.callback = callback; Dep.target = this; key.split('.').reduce((newObj, key) => newObj[key], vm.$data); Dep.target = null; } update() { const value = this.key.split('.').reduce((newObj, k) => newObj[k], this.vm.$data); this.callback(value); } }
这篇关于实现简易版的 Vue的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16Vue3资料:新手入门必读教程
- 2024-11-16Vue3资料:新手入门全面指南
- 2024-11-16Vue资料:新手入门完全指南
- 2024-11-16Vue项目实战:新手入门指南
- 2024-11-16React Hooks之useEffect案例详解
- 2024-11-16useRef案例详解:React中的useRef使用教程
- 2024-11-16React Hooks之useState案例详解
- 2024-11-16Vue入门指南:从零开始搭建第一个Vue项目
- 2024-11-16Vue3学习:新手入门教程与实践指南
- 2024-11-16Vue3学习:从入门到初级实战教程