溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

淺談Vue數(shù)據(jù)綁定的原理

發(fā)布時(shí)間:2020-08-28 03:54:46 來(lái)源:腳本之家 閱讀:116 作者:TMaize''''''''Blog 欄目:web開(kāi)發(fā)

本文介紹了Vue數(shù)據(jù)綁定的原理,分享給大家,具體如下:

原理

其實(shí)原理很簡(jiǎn)單,就是攔截了Object的get/set方法,在對(duì)數(shù)據(jù)進(jìn)行set (obj.aget=18) 時(shí)去重現(xiàn)渲染視圖

實(shí)現(xiàn)方式有兩種

方式1

定義了同名的get/set就相當(dāng)于定義了age

var test = {
  _age: 18,
  get age() {
   console.log('觸發(fā)get');
   //直接會(huì)this.age會(huì)進(jìn)入死遞歸的
   return this._age;
  },
  set age(age) {
   console.log('觸發(fā)set');
   this._age = age;
  }
 };

為了讓test不顯示多余的變量,可以把_age定義在外部

var _age = 18;
 var test = {
  get age() {
   console.log('觸發(fā)get');
   //直接會(huì)this.age會(huì)進(jìn)入死遞歸的
   return _age;
  },
  set age(age) {
   console.log('觸發(fā)set');
   _age = age;
  }
 };

方式2

使用這種方式完美的解決了對(duì)象內(nèi)包含多余的變量的問(wèn)題

function test() {
  var _age = 18;
  Object.defineProperty(this, "age", {
   get: function () {
    console.log('觸發(fā)get');
    return _age;
   },
   set: function (value) {
    console.log('觸發(fā)set')
    _age = value;
   }
  });
 }
 var t = new test();
 t.age=18;

實(shí)現(xiàn)數(shù)據(jù)到視圖的綁定

這里的渲染只是一個(gè)簡(jiǎn)單的正則替換

要實(shí)現(xiàn)Vue那么強(qiáng)大的功能還要自己實(shí)現(xiàn)一個(gè)模板引擎

淺談Vue數(shù)據(jù)綁定的原理 

<div id="test">
 <p>name:</p>
 <p>age:</p>
</div>
function Element(id, initData) {
 var self = this;
 var el = document.getElementById(id);
 var templet = el.innerHTML;
 var _data = null;

 if (initData) {
 _data = {};
 for (var variable in initData) {
  _data[variable] = initData[variable];
  bind(variable, self);
 }
 }

 function bind(variable, obj) {
 Object.defineProperty(self, variable, {
  set: function (value) {
  //使用_data里的數(shù)據(jù),避免死遞歸
  _data[variable] = value;
  //每次被設(shè)置新值的時(shí)候重新渲染界面
  render();
  },
  get: function () {
  return _data[variable];
  },
 });
 }

 //渲染
 function render() {
 var temp = templet;
 temp = temp.replace(/\{\{(.*)\}\}/g, function (s, t) {
  if (_data[t]) {
  return _data[t];
  }
 });
 el.innerHTML = temp;
 }

 //初始化時(shí)候手動(dòng)渲染一次
 render();
}

var app = new Element('test', {
 name: 'zhangsan',
 age: 18
})

實(shí)現(xiàn)視圖到數(shù)據(jù)的綁定

這里做一個(gè)簡(jiǎn)單的input改變的事件監(jiān)聽(tīng)

每次渲染之后都要重新添加事件,用時(shí)間委托可以實(shí)現(xiàn),但是input的focus位置不能保留

可見(jiàn)Vue內(nèi)部的渲染和事件綁定肯定不是像這里demo寫的那么簡(jiǎn)單,這里只是大致的原理(可能并不是這樣的。。。)

淺談Vue數(shù)據(jù)綁定的原理 

<div id="test">
 <input type="text" value="">
 <br>
 <span></span>
</div>
function Element(id, initData) {
 var self = this;
 var el = document.getElementById(id);
 var templet = el.innerHTML;
 var input = el.getElementsByTagName('input')[0];
 var _data = initData;

 Object.defineProperty(self, 'data', {
 set: function (value) {
  _data = value;
  render();
 },
 get: function () {
  return _data;
 },
 });

 //渲染
 function render() {
 var temp = templet;
 temp = temp.replace(/\{\{(data)\}\}/g, function (s, t) {
  return _data;
 });
 el.innerHTML = temp;

 //重新添加事件,其實(shí)應(yīng)該用事件委托的
 input = el.getElementsByTagName('input')[0];
 inputchange();
 input.focus();
 }

 function inputchange() {
 if (window.attachEvent) {
  input.attachEvent("oninput", temp);
 } else if (window.addEventListener) {
  input.addEventListener("input", temp, false);
 }

 function temp() {
  self.data = input.value;
 }
 }

 //初始化時(shí)候手動(dòng)渲染一次
 render();
}
var app = new Element('test', '');

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI