Vue教程06:數據同步、雙向綁定原理

閱讀更多系列文章請訪問個人GitHub博客,示例代碼請訪問這裏

利用Proxy實現數據同步

代碼示例:/lesson06/01. 數據同步git

利用Proxy攔截能夠對數據的修改,得知數據被修改時,將模板中相應屬性的部分替換,就完成了簡單的數據同步功能。github

const el = document.querySelector('#app')

// 獲取標籤內容做爲頁面模板
let template = el.innerHTML

// _data爲初始化
let _data = {
  name: 'lee',
  age: 18
}

// 爲_data設置攔截,經過修改data中屬性的值,來修改
let data = new Proxy(_data, {
  // 當數據修改時,會被set方法攔截,從而得知數據被修改的值value,以後能夠將value渲染到頁面中,obj爲_data
  set(obj, key, value) {
    console.log(`設置${key}屬性爲${value}`)
    obj[key] = value

    // 將數據渲染到頁面中
    render()
  }
})

// 初始化時渲染頁面
render()

function render() {
  // 將模板中{{}}內部的內容,用數據替換
  el.innerHTML = template.replace(/\{\{\w+\}\}/g, str => {
    str = str.substring(2, str.length - 2);

    return _data[str];
  })
}
複製代碼

HTML:bash

<div id="app">
  姓名:{{name}}<br/>
  年齡:{{age}}
</div>
複製代碼

數據雙向綁定

在data改變時,查找頁面中含有相應v-model屬性的input標籤,將input的value值改成data的值。 同時在input標籤的值變化時,將input的值設置爲data的值,就實現了雙向綁定。app

JavaScript:less

const el = document.querySelector('#app')

// 獲取標籤內容做爲頁面模板
let template = el.innerHTML

// _data爲初始化
let _data = {
  name: 'lee',
  age: 18
}

// 爲_data設置攔截,經過修改data中屬性的值,來修改
let data = new Proxy(_data, {
  // 當數據修改時,會被set方法攔截,從而得知數據被修改的值value,以後能夠將value渲染到頁面中,obj爲_data
  set(obj, key, value) {
    console.log(`設置${key}屬性爲${value}`)
    obj[key] = value

    // 將數據渲染到頁面中
    render()
  }
})

// 初始化時渲染頁面
render()

function render() {
  // 將模板中{{}}內部的內容,用數據替換
  el.innerHTML = template.replace(/\{\{\w+\}\}/g, str => {
    str = str.substring(2, str.length - 2);

    return _data[str];
  })

  // 但檢測到數據改變時,將input的值同步
  Array.from(document.getElementsByTagName('input'))
    // 查找含有v-model屬性,即設置了雙向綁定的input
    .filter((ele) => ele.getAttribute('v-model'))
    .forEach((input, index) => {
      const name = input.getAttribute('v-model')
      input.value = _data.name

      // 輸入框的值變化時,將data中相應屬性的值改變
      input.oninput = function () {
        data[name] = input.value
      }
    })
}
複製代碼

HTML:ui

<div id="app">
  <input type="text" v-model="name"><br />
  姓名:{{name}}<br/>
  年齡:{{age}}
</div>
複製代碼
相關文章
相關標籤/搜索