本文介绍了用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;">
TinyVue全部代码
{
let value = data[i]
Object.defineProperty(data,i,{
enumerable: true,configurable: true,get: function () {
return value;
},set: function (newVal) {
if (value !== newVal) {
value = newVal;
that._updater()
}
}
})
})
}
_initEvents(el,callBack) {
this.$el.querySelectorAll(el).forEach(i => {
if(i.hasAttribute(attr)) {
let key = i.getAttribute(attr)
callBack(i,key)
}
})
}
_initView(el,callBack) {
this.$el.querySelectorAll(el,callBack).forEach(i => {
if(i.hasAttribute(attr)) {
let key = i.getAttribute(attr),data = this.$data[key]
callBack(i,data)
}
})
}
_updater() {
this._initView('input,data) => {
i.value = data
})
this._initView('select',data) => {
i.querySelectorAll('option').forEach(v => {
if(v.value == data) v.setAttribute('selected',true)
else v.removeAttribute('selected')
})
})
let regExpInner = /\{{ *([\w_\-]+) *\}}/g
this.$el.querySelectorAll("*").forEach(i => {
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])
})
}
})
}
_compile() {
this._initEvents('*',key) => {
i.addEventListener('click',() => this.$methods[key].bind(this.$data)())
})
this._initEvents('input,key) => {
i.addEventListener('input',() => {
Object.assign(this.$data,{[key]: i.value})
})
})
this._initEvents('select',key) => {
i.addEventListener('change',{[key]: i.options[i.options.selectedindex].value}))
})
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。
原文地址:https://www.jb51.cc/vue/32701.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。