千家信息网

怎么使用ES6的class写一个双向绑定

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,今天小编给大家分享一下怎么使用ES6的class写一个双向绑定的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下
千家信息网最后更新 2026年11月01日怎么使用ES6的class写一个双向绑定

今天小编给大家分享一下怎么使用ES6的class写一个双向绑定的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

最终效果如下:

构造器(constructor)

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

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。

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

// el为元素tagName,attr为元素属性(v-model,@click)_initEvents(el, attr, callBack) { this.$el.querySelectorAll(el).forEach(i => {  if(i.hasAttribute(attr)) {   let key = i.getAttribute(attr)   callBack(i, key)  } })}

载入输入框事件

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

载入选择框事件

this._initEvents('select', 'v-model', (i, key) => { i.addEventListener('change', () => Object.assign(this.$data, {[key]: i.options[i.options.selectedIndex].value}))})

载入点击事件

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

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

视图更新器(updater)

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

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

更新输入框视图

this._initView('input, textarea', 'v-model', (i, key, data) => { i.value = data})

更新选择框视图

this._initView('select', 'v-model', (i, key, data) => { i.querySelectorAll('option').forEach(v => {  if(v.value == data) v.setAttribute('selected', true)  else v.removeAttribute('selected') })})

更新innerHTML

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

let regExpInner = /\{{ *([\w_\-]+) *\}}/gthis.$el.querySelectorAll("*").forEach(i => { let replaceList = i[xss_clean].match(regExpInner) || (i.hasAttribute('vueID') && i.getAttribute('vueID').match(regExpInner)) if(replaceList) {  if(!i.hasAttribute('vueID')) {   i.setAttribute('vueID', i[xss_clean])  }  i[xss_clean] = i.getAttribute('vueID')  replaceList.forEach(v => {   let key = v.slice(2, v.length - 2)   i[xss_clean] = i[xss_clean].replace(v, this.$data[key])  }) }})

监听器(watcher)

数据变化之后更新视图




您输入的是:{{text1}}+{{text2}}+{{text3}}

您选择了:{{select}}

TinyVue全部代码

class TinyVue{ constructor({el, data, methods}){  this.$data = data  this.$el = document.querySelector(el)  this.$methods = methods  this._compile()  this._updater()  this._watcher() } _watcher(data = this.$data) {  let that = this  Object.keys(data).forEach(i => {   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, attr, callBack) {  this.$el.querySelectorAll(el).forEach(i => {   if(i.hasAttribute(attr)) {    let key = i.getAttribute(attr)    callBack(i, key)   }  }) } _initView(el, attr, callBack) {  this.$el.querySelectorAll(el, attr, callBack).forEach(i => {   if(i.hasAttribute(attr)) {    let key = i.getAttribute(attr),     data = this.$data[key]    callBack(i, key, data)   }  }) } _updater() {  this._initView('input, textarea', 'v-model', (i, key, data) => {   i.value = data  })  this._initView('select', 'v-model', (i, key, 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[xss_clean].match(regExpInner) || (i.hasAttribute('vueID') && i.getAttribute('vueID').match(regExpInner))   if(replaceList) {    if(!i.hasAttribute('vueID')) {     i.setAttribute('vueID', i[xss_clean])    }    i[xss_clean] = i.getAttribute('vueID')    replaceList.forEach(v => {     let key = v.slice(2, v.length - 2)     i[xss_clean] = i[xss_clean].replace(v, this.$data[key])    })   }  }) } _compile() {  this._initEvents('*', '@click', (i, key) => {   i.addEventListener('click', () => this.$methods[key].bind(this.$data)())  })  this._initEvents('input, textarea', 'v-model', (i, key) => {   i.addEventListener('input', () => {    Object.assign(this.$data, {[key]: i.value})   })  })  this._initEvents('select', 'v-model', (i, key) => {   i.addEventListener('change', () => Object.assign(this.$data, {[key]: i.options[i.options.selectedIndex].value}))  }) }}

以上就是"怎么使用ES6的class写一个双向绑定"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。

事件 更新 视图 元素 知识 篇文章 输入 选择 双向 不同 内容 函数 很大 代码 大部分 对象 就是 属性 效果 数据 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州淘业互联网络科技 中关村互联网科技集团 互联网中国科技 互联网公司 科技公司 深圳互联网络科技有限公司 亿策互联网科技 浩特互联网科技 互联网科技宣传片 恒生科技互联网指数分析 湖南洣水互联网科技有限公司扣款 现代科技和互联网有关系吗 互联网金融中的现代科技 威龙国际互联网科技公司 恒生互联网科技业指数调整周期 众安科技工业互联网合作 云南省自由互联网科技有限公司 互联网安防科技感 广州互联网高科技取餐柜 美国五大互联网科技公司市值多少 互联网科技创新方面的资料 新华互联网科技学校 深圳恒合互联网络科技有限公司 互联网科技生活的内容 宁波青枫互联网科技有限公司 宜昌元轩互联网科技有限公司 黑科技 体验场景 互联网大会 陕西云淼互联网科技公司 国产互联网科技公司 上海万顺科技互联网有限公司招聘 第三届互联网大会安防黑科技
0