简易实现v-model轮子功能

学习手写v-model



  
用户 密码 手机
用户: {{ username }}
密码: {{ password }}
手机: {{ phone }}

下面是js部分

// 手写v-model
const varibleReg = /{{(.+?)}}/
// 1 先实现数据劫持
// 2 绑定input
// 3 渲染dom节点内容
class MVVM {

  constructor(el, data) {
    this.el = document.querySelector(el)
    this._data = data
    this.domPool = {}
    this.init()
  }

  setValue(key, value) {
    this.data[key] = value
  }

  bindInput(el) {
    const inputs = el.querySelectorAll('input[v-model]')
    inputs.forEach(input => {
      input.addEventListener('input', this.handleInput.bind(this, input))
    })
  }

  handleInput(input) {
    const key = input.getAttribute('v-model')
    const _value = input.value
    this.data[key] = _value
  }

  bindDom(el) {
    const childNodes = el.childNodes
    childNodes.forEach(item => {
      const _value = item?.nodeValue
      if (item?.nodeType === 3 && varibleReg.test(_value)) {
        const key = _value.match(varibleReg)[1].trim()
        this.domPool[key] = item.parentNode
        item.parentNode.innerText = this.data[key]
      }
      // 递归函数
      !!item?.childNodes.length && this.bindDom(item)
    })
  }

  initData() {
    this.data = {}
    for (const key in this._data) {
      Object.defineProperty(this.data, key, {
        get: () => this._data[key],
        set: newVal => {
          this._data[key] = newVal
          this.domPool[key].innerText = this.data[key]
        }
      })
    }
  }

  init() {
    this.initData()
    this.bindDom(this.el)
    this.bindInput(this.el)
  }

}

你可能感兴趣的:(简易实现v-model轮子功能)