Vue作為目前最火的框架之一,對于它的雙向數(shù)據(jù)綁定原理很多人都會有些疑惑蛙吏,今天在這邊兄一,我用比較淺顯洲赵、易理解的小例子來給大家的簡單的講解一下鸳惯。
vue數(shù)據(jù)雙向綁定原理
先來看一下數(shù)據(jù)雙向綁定的一個效果來初步感受一下它的神奇之處。
<body>
<div id="app">
<input type="text" v-model="msg">
<!-- v-model屬于表單輸入的一個指令叠萍,實質(zhì)是一個屬性悲敷,屬性值是一個變量 -->
{{ msg }}
<!-- 數(shù)據(jù)綁定最常見的形式-Mustache語法的文本差值,{{}}將會被替換成對應(yīng)數(shù)據(jù)對象上msg的值 -->
</div>
</body>
<script src="vue.js"></script>
<script >
new Vue({
el:"#app", //找到要使用Vue語法的DOM節(jié)點
data:{ //初始化的數(shù)據(jù)
msg:"hello vue" //定義了msg的值
}
})
</script>
整體效果參考下圖(此圖不是上述代碼效果)
下面探討一下原理俭令。
vue數(shù)據(jù)雙向綁定是通過 數(shù)據(jù)劫持 結(jié)合 發(fā)布者-訂閱者模式 的方式來實現(xiàn)的.
首先來看一下數(shù)據(jù)劫持-數(shù)據(jù)劫持的實現(xiàn)方式 Object.defineProperty()后德。
Object.defineProperty()
Object.defineProperty()方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現(xiàn)有屬性抄腔,并且返回這個對象瓢湃。
語法 Object.defineProperty(obj,prop,descriptor)
obj:要在其上定義屬性的對象
prop:要定義或者修改的屬性的名稱
descriptor:將被定義或修改的屬性描述符
返回值:被傳遞給函數(shù)的對象
如果上述解釋仍然不明白,下面我們看下Object.defineProperty()方法的具體使用案例
<script>
var Book = {name:"java權(quán)威指南"};
console.log(Book.name);
let val;
Object.defineProperty(Book,"name",{
set(value){
val=value;
},
get(){
console.log(val); //打印這里的值可以看出赫蛇,val被修改了绵患。
return val; //這里就是返回值
}
})
console.log(Book);
Book.name="HTML5權(quán)威指南"; //這里調(diào)用了set方法,這里實際上將“html5權(quán)威指南作為參數(shù)value”傳入了set方法并賦值給了val悟耘;
console.log(Book.name); //這里調(diào)用了get方法落蝙,獲取了修改后的val的值
</script>
運行結(jié)果如上:最終Book對象上的name屬性通過get,set方法就成功的進(jìn)行了修改暂幼》だ眨看到第22行的輸出結(jié)果也可以看出,val的值被修改傳遞旺嬉。
查看Book對象也會發(fā)現(xiàn)上面綁定了get和set方法管行。
利用Object.defineProperty()的這個特點,當(dāng)你把一個普通的 JavaScript 對象傳入 Vue 實例作為 data 選項邪媳,Vue 將遍歷此對象所有的屬性捐顷,并使用 Object.defineProperty 把這些屬性全部轉(zhuǎn)為 getter/setter。
我們可以先來看一下通過控制臺輸出一個定義在vue初始化數(shù)據(jù)上的對象是個什么東西雨效。是否這個vue對象如上述所說擁有g(shù)et和set方法迅涮。
<script src="vue.js"></script>
<script>
var vm=new Vue({
data:{
obj:{
a:1
}
},
created: function () {
console.log(this.obj);
}
})
</script>
我們可以看到屬性a有兩個相對應(yīng)的get和set方法,為什么會多出這兩個方法呢徽龟?因為vue是通過上述講的Object.defineProperty()來實現(xiàn)數(shù)據(jù)劫持的叮姑。
發(fā)布-訂閱者模式
又叫觀察者模式,它定義了一對多的關(guān)系顿肺,讓多個觀察者可以同時監(jiān)聽一個對象戏溺。
它的最主要的思想:這個對象狀態(tài)變化時就會通過所有的觀察者對象,使得它們能夠自動更新屠尊。
最上面的雙向綁定案例的思想簡單分析:
vue內(nèi)部通過Object.defineProperty( )對屬性設(shè)置一個set函數(shù)旷祸,當(dāng)input中輸入的值發(fā)生了改變了就會來觸發(fā)這個函數(shù),然后得到新的msg的值通過{{}}將新得到的msg值反應(yīng)到頁面上讼昆。
最基礎(chǔ)的理解就在上方托享,如果還要更深層次的理解還要對原理圖去理解,下面我會放一張原理圖浸赫,大家如果學(xué)有余力可以再去學(xué)習(xí)哦~