SOURCE

class Mvvm {
    constructor (options) {
        const {el,data,methods} = options;
        this.methods = methods
        this.target = null,
        this.observe (this,data);
        this.compile(document.getElementById(el))
    }
    observe(root,data){
        for (const key in data) {
            this.defineReactive(root,key,data[key])
        }
    }
    defineReactive(root,key,value){
        if(typeof value === "object"){
            return this.observe(value,value)
        }
        const dep = new Dispatcher();
        Object.defineProperty(root,key,{
            set(newValue) {
                if (value === newValue) return
                value = newValue
                dep.notify(newValue)
            },
            get(){
                dep.add(this.target)
                return value
            }
        })
    }
    compile(dom){
        const nodes = dom.childNodes;
        for (const node of nodes) {
            // 1是元素节点
            if (node.nodeType === 1) {
                const attrs = node.attributes;
                for (const attr of attrs) {
                    if (attr.name === 'v-model') {
                        const name = attr.value;
                        node.addEventListener('input',e => {
                            this[name] = e.target.value;
                        })
                        this.target = new Watcher(node,'input');
                        this[name]
                    }
                    if (attr.name === '@click'){
                        const name = attr.value;
                        node.addEventListener('click',this.methods[name].bind(this))
                    }
                }
            }
            // 3是文本节点
            if (node.nodeType == 3) {
                const reg = /\{\{(.*)\}\}/;
                const match = node.nodeValue.match(reg);
                if (match) {
                    const name = match[1].trim();
                    this.target = new Watcher(node, 'text');
                    this[name];
                }
            }
        }
    }
}

class Dispatcher {
    constructor() {
        this.watchers = []
    }
    add(watchers) {
        this.watchers.push(watchers)
    }
    notify(value) {
        this.watchers.forEach(watchers => watchers.update(value))
    }
}

class Watcher {
    constructor(node,type) {
        this.node = node;
        this.type = type;
    }
    update(value) {
        if (this.type == 'input') {
            this.node.value = value;
        }
        if (this.type == 'text') {
            this.node.nodeValue = value;
        }
    }
}
console 命令行工具 X clear

                    
>
console