页面代码:

<!DOCTYPE html><html lang="en"><head>    <title>Document</title>    <script src="./myvue.js"></script></head><body>    <div id="app">        {{ name }}        <div>{{ message }}</div>        <input v-model="test" type="text">        {{ test }}    </div>    <script type="text/javascript">      let vm =  new vue({            el: '#app',            data: {                name: 'lili',                message: 'test',                test: '双向绑定'            }        })        // console.log(vm);        // console.log(vm._data.name);    </script></body></html>

myvue.js代码:

class vue extends EventTarget{ // 定义自定义事件,须要继承EventTarget    constructor(option) {        super() // 继承要执行父类的构造函数        this.option = option        this._data = this.option.data        this.el = document.querySelector(this.option.el)        this.observe(this._data)        this.compileNode(this.el)    }    observe(data) {        let self = this        this._data = new Proxy(data, {            set(target, prop, newValue) {                console.log(newValue);                let event = new CustomEvent(prop, { // 发送自定义事件,实现双绑                    detail: newValue                })                self.dispatchEvent(event)                return Reflect.set(...arguments)            }        })    }    compileNode(el) {        let child = el.childNodes // 伪数组        console.log(child);        [...child].forEach(node => { // 伪数开展为数组            if(node.nodeType === 3) { // 文本节点                console.log('这是一个文本节点');                let text = node.textContent                let reg = /\{\{\s*([^\s\{\}]+)\s*\}\}/g                if (reg.test(text)) {                    let $1 = RegExp.$1 // 与正则表达式匹配的第一个 子匹配                    this._data[$1] && (node.textContent = text.replace(reg, this._data[$1]))                                        this.addEventListener($1, e=> { // 接管自定义事件,实现双绑                        node.textContent = text.replace(reg, e.detail)                    })                }            } else if (node.nodeType === 1) {                console.log('这是一个元素节点');                let attr = node.attributes                if(attr.hasOwnProperty('v-model')) {                    let keyName = attr['v-model'].nodeValue                    node.value = this._data[keyName]                    node.addEventListener('input', e => {                        this._data[keyName] = node.value                    })                }                this.compileNode(node)            }        })    }}