1.0.1 • Published 4 years ago

dvue v1.0.1

Weekly downloads
3
License
ISC
Repository
-
Last release
4 years ago

vue核心原理演示

数据劫持

模板编译

import Watcher from './watcher.js';
export default class Compiler {
    constructor(context) {
        this.$el = document.querySelector(context.$el);
        this.$data = context.$data;
        this.context = context;
        // 将dom节点转换成虚拟文档片段   
        this.$fragment = this.nodeToFragment(this.$el);
        // 编译虚拟文档片段
        this.compiler(this.$fragment);
        // 将虚拟文档片段挂载到dom树上
        this.$el.appendChild(this.$fragment);
    }

    // 将dom节点转换成虚拟文档片段
    nodeToFragment(node) {
        // 创建一个虚拟文档片段(对其进行操作不会触发dom回流)
        let fragment = document.createDocumentFragment();
        // 将页面中元素节点添加到虚拟文档片段上
        node.childNodes.forEach(child => {
            // 元素节点和非空文本节点, 都需要追加到虚拟文档片段中
            if(child.nodeType===3&&child.textContent.trim()!==''||child.nodeType===1){
                fragment.appendChild(child);
            }
        });
        // 将虚拟文档片返回
        return fragment;
    }

    // 执行模板编译
    compiler(node) {
        // 通过循环遍历, 执行正则表达式
        node.childNodes.forEach(child => {
            this.compilerTextNode(child);
        });
    }


    // 编译文本内容
    compilerTextNode(node) {
        // 匹配插值表达式的正则表达式
        const reg = /\{\{(.+?)\}\}/g;
        // 执行模板编译
        const pieces = node.textContent.split(reg);
        const matches = node.textContent.match(reg);
        let tokens = [];
        pieces.forEach(item => {
            if (matches && matches.indexOf(`{{${item}}}`) !== -1) {
                tokens.push('(' + item + ')');
            } else {
                tokens.push('`' + item + '`');
            }
        });
        new Watcher(tokens.join('+'), this.context, value => {
            // 更新节点内容
            node.textContent = value;
        });
    }

}

发布者订阅者模式

// 观察者模式中 通知
export default class Dep {
    constructor() {
        // 存放所有watcher
        // this.subs = {0:{update},1:{update}}
        this.subs = {}
    }

    addSub(target) {
        this.subs[target.uid] = target
    }

    notify() {
        for (let uid in this.subs) {
            this.subs[uid].update()
        }
    }
}
1.0.1

4 years ago

1.0.0

4 years ago