60行代碼 | Proxy實現一個數據驅動簡易DEMO

運行截圖

截圖

本文能作的

  1. 帶你瞭解一下Proxy的使用
  2. 瞭解經過插值表達式怎麼實現簡易版的數據驅動
  3. 代碼僅是簡單Demo,參考了50行代碼的MVVM,感覺閉包的藝術,一篇好文章,由於時間,沉底了,掏出來再學習一下~
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>pVue-proxy-mvvm</title>
</head>

<body>
  <div id="app">
    <p>hello, {{ name }}</p>
    <div>
      <span>author: {{ author }}</span>
      <span style="margin-left: 24px">time: {{ time }}</span>
    </div>
  </div>

  <script> // 當初始的 HTML 文檔被徹底加載和解析完成以後,DOMContentLoaded 事件被觸發, 無需等待樣式表、圖像和子框架的完成加載。 document.addEventListener("DOMContentLoaded", () => { const vm = new pVue({ el: "#app", data: { name: "Proxy", time: new Date(), author: "arley", }, }) for (let i = 0; i < 10; i++) { setTimeout(() => { this.data.name = `pVue, update: ${i}` // this === window }, 200 * (i + 1)) } }) class pVue { constructor(options) { const { el, data } = options this.options = options this._nodes = {} // 存在插值表達式的節點 window.data = this.onProxy(data) // 監聽數據變化 this.render(document.querySelector(el)) // 首次替換插值表達式爲data內的初始值 } onProxy(data) { const that = this const handler = { set(target, property, value, receiver) { // 監聽到值變化,再一次替換插值表達式爲新值 that._nodes[property].node.innerHTML = that._nodes[property].defaultData.replace( new RegExp(`{{\\s*${property}\\s*}}`, "g"), value ) return Reflect.set(target, property, value) }, } return new Proxy(data, handler) } render(node) { Array.prototype.forEach.call(node.childNodes, (child) => { if ( !child.firstElementChild && /\{\{(.+?)\}\}/.test(child.innerHTML) ) { const key = RegExp.$1.trim() this._nodes[key] = { // 保存含有插值的dom節點 和 本來的插值表達式內容 node: child, defaultData: child.innerHTML } // 替換插值表達式爲data的真正內容 child.innerHTML = child.innerHTML.replace( new RegExp(`{{\\s*${key}\\s*}}`, "g"), this.options.data[key] ) } else if (child.firstElementChild) { // 當前節點下還有其餘節點 this.render(child) } }) } } </script>
</body>

</html>
複製代碼

結尾討論

Vue中的MVVM和Vue的對應關係究竟是什麼樣子的吶?由於看到了不少不一樣的版本,有疑惑。javascript

  • M: xxx
  • V: xxx
  • VM: xxx
相關文章
相關標籤/搜索