vue模板实现4-高效更新

2018-05-13  本文已影响0人  恒星的背影
class Vue {                                            // Vue 类
  constructor(obj) {
    let {el, data} = obj
    const node = document.querySelector(el)
    const dataBindNode = {}

    data = new Proxy(data, {
      get(tar, key){
        return tar[key]
      },
      set(tar, key, val){
        tar[key] = val
        updateText(dataBindNode[key], data)
      }
    })

    this.data = data

    traverseNode(node, data, dataBindNode)

    for(let key in dataBindNode) {          // 第一次更新
      updateText(dataBindNode[key], data)
    }
  }
}

const updateText = (node, data) => {                    // 更新数据对应的文本节点
  const reg = /{{\w+}}/g
  const arr = node.text.match(reg) || []
  let text = node.text

  arr.forEach((item)=>{
    const name = item.slice(2, -2)

    if(data[name]) {
      node.node.textContent = text = text.replace(item, data[name])
    }
  })
}
const traverseNode = (node, data, dataBindNode) => {      // 遍历
  node.childNodes.forEach(item => {
    if(item.nodeName === '#text') {
      bindNode(item, data, dataBindNode)
    }
    else {
      traverseNode(item, data, dataBindNode)
    }
  });
}

const bindNode = (node, data, dataBindNode) => {          // 绑定
  const reg = /{{\w+}}/g
  const arr = node.textContent.match(reg) || []

  arr.forEach((item)=>{
    const key = item.slice(2, -2)
    if(data[key]) {
      dataBindNode[key] = {}
      dataBindNode[key].node = node
      dataBindNode[key].text = node.textContent
    }
    else { }  // 数据未定义却使用
  })
}
上一篇 下一篇

猜你喜欢

热点阅读