用ES6的class模仿Vue写一个双向绑定的示例代码

本文介绍了用ES6的class模仿Vue写一个双向绑定的示例代码分享给大家,具体如下:

最终效果如下:

构造器(constructor)

构造一个TinyVue对象,包含基本的el,data,methods

rush:js;"> class TinyVue{ constructor({el,data,methods}){ this.$data = data this.$el = document.querySelector(el) this.$methods = methods // 初始化 this._compile() this._updater() this._watcher() } }

编译器(compile)

用于解析绑定到输入框和下拉框的v-model和元素的点击事件@click。

先创建一个函数用来载入事件:

{ if(i.hasAttribute(attr)) { let key = i.getAttribute(attr) callBack(i,key) } }) }

载入输入框事件

{ i.addEventListener('input',() => { Object.assign(this.$data,{[key]: i.value}) }) })

载入选择框事件

{ i.addEventListener('change',() => Object.assign(this.$data,{[key]: i.options[i.options.selectedindex].value})) })

载入点击事件

点击事件对应的是methods中的事件

{ i.addEventListener('click',() => this.$methods[key].bind(this.$data)()) })

视图更新器(updater)

同理先创建公共函数来处理不同元素中的视图,包括input、textarea的value,select的选择值,div的innerHTML

{ if(i.hasAttribute(attr)) { let key = i.getAttribute(attr),data = this.$data[key] callBack(i,key,data) } }) }

更新输入框视图

{ i.value = data })

更新选择框视图

{ i.querySelectorAll('option').forEach(v => { if(v.value == data) v.setAttribute('selected',true) else v.removeAttribute('selected') }) })

更新innerHTML

这里实现方法有点low,仅想到正则替换{{text}}

{ let replaceList = i.innerHTML.match(regExpInner) || (i.hasAttribute('vueID') && i.getAttribute('vueID').match(regExpInner)) if(replaceList) { if(!i.hasAttribute('vueID')) { i.setAttribute('vueID',i.innerHTML) } i.innerHTML = i.getAttribute('vueID') replaceList.forEach(v => { let key = v.slice(2,v.length - 2) i.innerHTML = i.innerHTML.replace(v,this.$data[key]) }) } })

监听器(watcher)

数据变化之后更新视图

rush:xhtml;">