Vue渲染原理及其雙向資料繫結詳解
雙向資料繫結原理
1. 新建vue例項
var data = {
text:'hello world!'
};
var vm = new Vue({
el:'#app',
data
});
2. 將vue例項中的el HTML模板渲染進DOM
function nodeToFragment(node,vm) {
var frag = document.createDocumentFragment(),//建立DocumentFragment片段
child;
while (child = node.firstChild){//依次取node的子節點將其新增到frag中,
compile(child,vm);//新增到DOM之前需對child和Vue例項進行繫結以監聽彼此的變化
frag.appendChild(child);//此方法會同時刪除node中的child節點
}
return frag;
}
var dom = nodeToFragment(document.getElementById(id),this);
document.getElementById(id).appendChild(dom);//將上面返回的節點新增進DOM
3. 將vue例項中的el HTML模板渲染進DOM,compile詳解
function compile(node,vm) {//node為el的子節點
var reg = /\{\{(.*)\}\}/,// .為匹配除\r\n之外的任意單個字元,*為匹配前面字元任意多次
name;
//元素節點
if(node.nodeType == 1){
var attr = node.attributes;
for(var i = 0; i<attr.length; i++){//遍歷el的子節點的屬性,若其有v-model屬性,變從vm.data中取v-model屬性對應的值value,將value作為el的子節點的value|innerHTML值,因為v-model一般對應input元素
if(attr[i].nodeName == 'v-model'){
VModelEle.push(node);
name = attr[i].nodeValue;
node.value = vm.data[name];
node.innerHTML= vm.data[name];
node.addEventListener('input',function (e) {
vm.data[name] = e.target.value;
});//此處已假定node為input元素,監聽此input,若其value有變化則將其反映到vm.data的name中,name為'v-model'屬性對應的nodeValue。到這裡,已經實現了DOM到vm.data的繫結。
new Watcher(vm,node,name);//這一步實現vm.data到DOM的繫結
node.removeAttribute('v-model');//從node中刪除v-model屬性。
break;
}
}
}
//若node為文字節點,判斷文字節點的值是不是{{}}這種形式。
if(node.nodeType == 3){
if(reg.test(node.nodeValue)){
name = RegExp.$1;//RegExp為全域性物件,$1-$9為最新匹配到的9個正則表示式中帶括號的項,只能儲存最新9個
name = name.trim();//取reg = /\{\{(.*)\}\}/中括號內匹配到的值,name在vm.data中也有
new Watcher(vm,node,name);//為vm.name新增監聽器,實現從vm到DOM的繫結
}
}
}
4. 為vm.name新增監聽器,new Watcher(vm,node,name)
- Dep方法詳情
function Dep() {
this.subs = [];
}
Dep.prototype = {
addSub:function (sub) {
this.subs.push(sub);//sub為Watcher例項
},
notify:function () {
this.subs.forEach(function (sub) {
sub.update();//通知所有Watcher更新DOM
})
}
};
- Watcher方法詳情
function Watcher(vm,node,name) {
Dep.target = this;
this.name = name;
this.node = node;
this.vm = vm;
this.update();//每次new Watcher時都要用vm.data[this.name]資料更新this.node.nodeValue,即實現vm.data到DOM的繫結。
Dep.target = null;
}
Watcher.prototype = {
update:function () {
this.node.nodeValue = this.vm.data[this.name];
}
};
- 為
vm.data
中的每個資料重寫其Object.defineProperty
中的set
和get
方法
function observe(obj) {
Object.keys(obj).forEach(function (key) {
defineReactive(obj,key,obj[key]);
})
}
function defineReactive(obj,key,val){
//defineReactive即為每個data屬性新增setter和getter,當在外部重新為data新增新屬性時,還會呼叫此方法,介面為Vue.$set(obj,kay,value);。
var dep = new Dep();
Object.defineProperty(obj,key,{
//因為讀取vm.data的地方比較多,比如compile方法中的node.value =vm.data[name];node.innerHTML= vm.data[name];而只有第一次為vm.data[name]新增Watcher時才需將此Watcher新增進Dep的subs中,因為new Watcher會執行Watcher的update方法,其中會讀取this.vm.data[this.name]。
get:function () {
if(Dep.target){
dep.addSub(Dep.target);
}
return val;
},
//當重寫vm.data中的屬性時,就重置vModelEles中元素的value,vModelEles為所有有v-model屬性的元素
set:function (value) {
for(var ele in vModelEles){
vModelEles[ele].value = value;
}
if(value == val) return;
//若兩次值不同,將呼叫dep.notify方法,啟動所有Watcher,更改nodeValue
val = value;
dep.notify();
console.log(val);
}
});
}
雙向資料繫結原理總結
- 從DOM到vm.data很簡單,即addEventListener監聽DOM的變化,將其值寫到vm.data中即可。
- 從vm.data到DOM:
- 為出現在DOM中的vm.data中的每個元素新增Watcher,所有的Watcher都存放在Dep的subs中
- 每當vm.data有變化就呼叫Dep的notify方法,即取出所有subs中的Watcher,呼叫Watcher的updata方法,更新DOM
相關推薦
Vue渲染原理及其雙向資料繫結詳解
雙向資料繫結原理 1. 新建vue例項 var data = { text:'hello world!' }; var vm = new Vue({
vue.js和angular雙向資料繫結的實現原理
一、vue雙向資料繫結 1、原理 資料劫持: vue.js 是採用資料劫持結合釋出者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在資料變動時釋出訊息給訂閱者,觸發相應的監聽回撥。 2、實現步驟 要實現mv
vue的思中雙向資料繫結的原理
我們在面試中經常會被問道什麼是mvc 什麼是 mvvm 還有雙向資料繫結的原理:MVC:對專案的整體把控,M代表的是資料庫中的資料,V代表的是前端的檢視層,C用於處理M和V之間進行互動的業務邏輯(業務
vue.js v-model雙向資料繫結, vue.js form表單資料繫結
vue.js v-model雙向資料繫結, vue.js form表單資料繫結 ================================ ©Copyright 蕃薯耀 2018年11月29日 http://fanshuyao.iteye.com/ &l
vue指令v-model(雙向資料繫結)自動收集資料
前言:表單提交資料在網站頁面中是十分常見的,而這個表單資料的獲取在原生寫法甚至於JQ都是比較麻煩的(首先需要獲取DOM,然後獲取值)。 但是,在vue的專案環境下,表單資料的收集又該怎麼辦呢?(這種自己寫input元素的方法在實際專案中是不常用的哈,因為一般我們都會用一個UI庫,方便而快捷!
【Vue】原始碼分析--雙向資料繫結的實現
總結 Vue的雙向資料繫結主要通過Object.defineProperty來實現,先為所有的屬性加上get/set的監控,這樣當屬性值改變時就會觸發對應的set方法,然後再在set方法中通過觀
SpringMVC型別轉換、資料繫結詳解[附帶原始碼分析]
目錄 前言 SpringMVC是目前主流的Web MVC框架之一。 public String method(Integer num, Date birth) { ... } Http請求傳遞的資料都是字串String型別的,上面這個方法在Contro
WPF 資料繫結詳解。。。
資料繫結 控制元件之間的繫結 繫結源 source 資料提供者 繫結物件 target 接受資料的物件,被繫結的物件 對 繫結物件 進行資料繫結,將其的屬性,和繫結源的某個屬性進行繫結 純 xaml 繫結 < Grid > < T
轉 vue實現雙向資料繫結之原理及實現篇 vue的雙向繫結原理及實現
轉自:canfoo#! vue的雙向繫結原理及實現 前言 先上個成果圖來吸引各位: 程式碼: &nb
angular,vue,react的基本語法—雙向資料繫結、條件渲染、列表渲染、angular小案例
基本語法: 1、雙向資料繫結 vue 指令:v-model="msg" react constructor(){ this.state{ msg:"雙向資料繫結" } render(){ <input type="text" value={this.state
vue中實現雙向資料繫結原理,使用了Object.defineproperty()方法,方法簡單
在vue中雙向資料繫結原理,我們一般都是用v-model來實現的 ,但一般在面試話會問到其實現的原理, 方法比較簡單,就是利用了es5中的一個方法.Object.defineproperty(),它有三個引數, Object.defineproperty(obj,'val',attrObject), 引數
詳解 vue 雙向資料繫結的原理,並實現一組雙向資料繫結
1:vue 雙向資料繫結的原理: Object.defineProperty是ES5新增的一個API,其作用是給物件的屬性增加更多的控制Object.defineProperty(obj, prop, descriptor)引數 obj: 需要定義屬性的物件(目標物件)prop: 需被定義或修改的屬性名(物
vue雙向資料繫結原理
Vue應用的是mvvm框架,view和model分離,然後通過vm雙向資料繫結,` <code class="hljs handlebars has-numbering" style="display: block; padding: 0px; color: inh
Vue.js雙向資料繫結原理
vue雙向繫結就是指model層與view層的同步,兩者之間任意一個發生變化都會同步更新到另一者。 View為檢視層,Model為資料層,ViewModel為邏輯控制層。 vue.js採用資料劫持結合釋出者-訂閱者模式的方法,通過Object.defin
vue雙向資料繫結的原理
有關雙向資料繫結的原理 最近兩次面試的時候,被問到了vue中雙向資料繫結的原理,因為初學不精,只是使用而沒有深入研究,所以答不出來。之後就在網上查找了別人寫的部落格,學習一下。 下面是部落格園一篇部落格,以及MDN上講解Object.defineProper
vue 雙向資料繫結原理
Vue的雙向資料繫結原理是什麼?vue.js是採用資料劫持結合釋出者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter, getter,在資料變動時釋出訊息給訂閱者,出發相應的監聽回撥。具體步驟:首先Vue會使用document
單項資料繫結、雙向資料繫結及其原理(髒檢查)
參考文章: https://segmentfault.com/q/1010000002511449/a-1020000002514653 單向資料繫結:指的是我們先把模板寫好,然後把模板和資料(資料可
Vue雙向資料繫結原理解析
首先上原始碼,模擬vue的雙向資料繫結原理<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Two-way data-
深入vue原始碼,瞭解vue的雙向資料繫結原理
大家都知道vue是一種MVVM開發模式,資料驅動檢視的前端框架,並且內部已經實現了雙向資料繫結,那麼雙向資料繫結是怎麼實現的呢? 先手動擼一個最最最簡單的雙向資料繫結 1 <div> 2 <input type="text" name="" id="te
面試題:你能寫一個Vue的雙向資料繫結嗎?
在目前的前端面試中,vue的雙向資料繫結已經成為了一個非常容易考到的點,即使不能當場寫出來,至少也要能說出原理。本篇文章中我將會仿照vue寫一個雙向資料繫結的例項,名字就叫myVue吧。結合註釋,希望能讓大家有所收穫。 1、原理 Vue的雙向資料繫結的原理相信大家也都十分了解了,主要是通過 Obje