国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

vue.js 實現v-model與{{}}指令方法

2024-05-06 15:28:19
字體:
來源:轉載
供稿:網友

上次我們已經分析了vue.js是通過Object.defineProperty以及發布訂閱模式來進行數據劫持和監聽,并且實現了一個簡單的demo。今天,我們就基于上一節的代碼,來實現一個MVVM類,將其與html結合在一起,并且實現v-model以及{{}}語法。

tips:本節新增代碼(去除注釋)在一百行左右。使用的Observer和Watcher都是延用上一節的代碼,沒有修改。

接下來,讓我們一步步來,實現一個MVVM類。

構造函數

首先,一個MVVM的構造函數如下(和vue.js的構造函數一樣):

class MVVM { constructor({ data, el }) {  this.data = data;  this.el = el;  this.init();  this.initDom(); }}

和vue.js一樣,有它的data屬性以及el元素。

初始化操作

vue.js可以通過this.xxx的方法來直接訪問this.data.xxx的屬性,這一點是怎么做到的呢?其實答案很簡單,它是通過Object.defineProperty來做手腳,當你訪問this.xxx的時候,它返回的其實是this.data.xxx。當你修改this.xxx值的時候,其實修改的是this.data.xxx的值。具體可以看如下代碼:

class MVVM { constructor({ data, el }) {  this.data = data;  this.el = el;  this.init();  this.initDom(); } // 初始化 init() {  // 對this.data進行數據劫持  new Observer(this.data);  // 傳入的el可以是selector,也可以是元素,因此我們要在這里做一層處理,保證this.$el的值是一個元素節點  this.$el = this.isElementNode(this.el) ? this.el : document.querySelector(this.el);  // 將this.data的屬性都綁定到this上,這樣用戶就可以直接通過this.xxx來訪問this.data.xxx的值  for (let key in this.data) {   this.defineReactive(key);  } } defineReactive(key) {  Object.defineProperty(this, key, {   get() {    return this.data[key];   },   set(newVal) {    this.data[key] = newVal;   } //前端全棧學習交流圈:866109386  })//面向1-3年前端開發人員 }//幫助突破技術瓶頸,提升思維能力。 // 是否是屬性節點 isElementNode(node) {  return node.nodeType === 1; }}

在完成初始化操作后,我們需要對this.$el的節點進行編譯。目前我們要實現的語法有v-model和{{}}語法,v-model這個屬性只可能會出現在元素節點的attributes里,而{{}}語法則是出現在文本節點里。

fragment

在對節點進行編譯之前,我們先考慮一個現實問題:如果我們在編譯過程中直接操作DOM節點的話,每一次修改DOM都會導致DOM的回流或重繪,而這一部分性能損耗是很沒有必要的。因此,我們可以利用fragment,將節點轉化為fragment,然后在fragment里編譯完成后,再將其放回到頁面上。

class MVVM { constructor({ data, el }) {  this.data = data;  this.el = el;//前端全棧交流學習圈:866109386  this.init();//針對1-3年前端開發人員  this.initDom();//幫助突破技術瓶頸,提升思維能力。 } initDom() {  const fragment = this.node2Fragment();  this.compile(fragment);  // 將fragment返回到頁面中  document.body.appendChild(fragment); } // 將節點轉為fragment,通過fragment來操作DOM,可以獲得更高的效率 // 因為如果直接操作DOM節點的話,每次修改DOM都會導致DOM的回流或重繪,而將其放在fragment里,修改fragment不會導致DOM回流和重繪 // 當在fragment一次性修改完后,在直接放回到DOM節點中 node2Fragment() {  const fragment = document.createDocumentFragment();  let firstChild;  while(firstChild = this.$el.firstChild) {   fragment.appendChild(firstChild);  }  return fragment; }}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 莱阳市| 瑞丽市| 桓仁| 咸丰县| 永兴县| 富源县| 永顺县| 皮山县| 九台市| 日照市| 揭东县| 崇信县| 呼伦贝尔市| 扎赉特旗| 瑞安市| 磐石市| 灵台县| 谷城县| 定南县| 邹平县| 墨竹工卡县| 崇信县| 洛宁县| 甘南县| 舟曲县| 泗阳县| 通江县| 抚远县| 罗江县| 大厂| 溧阳市| 四川省| 巴中市| 德阳市| 宾阳县| 六安市| 杂多县| 遂宁市| 江北区| 壶关县| 商洛市|