vue實現數據控制視圖的原理解析
這篇主要講的就是vue很重要的一塊知識點,雙向數據綁定是如何實現的。一開始看這一塊的內容的時候比較迷茫,迷茫在以下幾個點:
- 這塊內容該從哪邊入手
- 數據變化是如何驅動視圖層更新的
- 做題深化知識點
從哪邊著手去看響應式原理
我這邊提供三個方向,從這三個方向,你都可以看到watcher的使用,然后watcher的使用過程中,會摻雜到observer以及dep,然后以點帶面,對整體進行梳理
初始化的render流程去看
在lifecycle這個文件中的mountComponent這個方法里,創(chuàng)建了一個watcher。代碼如下:
new Watcher(vm, updateComponent, noop, {
before () {
if (vm._isMounted && !vm._isDestroyed) {
callHook(vm, 'beforeUpdate')
}
}
}, true /* isRenderWatcher */)
可以透過這個傳參,梳理出整一個
- 從watch的角度去看
- 從computed的角度去看
數據變化是如何驅動視圖層更新的
這個問題其實可以分兩個方面去看:
如何知道數據變化了
如何知道某一塊視圖和數據有關,并更新他 如何知道數據變化了
答案:數據劫持
數據劫持的兩種方式
Object.defineProperty proxy
Vue3.0中的數據劫持是用proxy來實現的,目前閱讀的源碼中,都是以 Object.defineProperty 這種方式來實現的。
如何知道某一塊視圖和數據有關,并更新他
答案:依賴收集以及訂閱更新
詳細解讀過程:用圖告訴你響應式原理
這里僅用一個簡單的例子和圖,來明確一下整個流程
<div id="app">
{{ message }}
{{ message1 }}
<input type="text" v-model="message">
<div @click="changeMessage">改變message</div>
</div>
var app = new Vue({
el: '#app',
data: {
message: '1',
message1: '2',
},
methods: {
changeMessage() {
this.message = '2'
}
},
watch: {
message: function(val) {
this.message1 = val
}
}
})
依賴收集流程圖
依賴收集的最終結果:
訂閱更新流程圖:
。
做題深化知識點
題目如下:
1、簡述Vue的響應式原理
2、計算屬性和watch的區(qū)別
3、Vue中給data中的對象屬性添加一個新的屬性時會發(fā)生什么,如何解決?
對于第一和第二在這里就不花篇幅去說明。
Vue中給data中的對象屬性添加一個新的屬性時會發(fā)生什么,如何解決?
我們在做業(yè)務的時候經常會遇到這樣的情況,我舉一個簡單的例子:
<template>
<div>
<ul>
<li v-for="value in obj" :key="value">
{{value}}
</li>
</ul>
<button @click="addObjB">添加obj.b</button>
</div>
</template>
<script>
export default {
data () {
return {
obj: {
a: 'obj.a'
}
}
},
methods: {
addObjB () {
this.obj.b = 'obj.b'
console.log(this.obj)
}
}
}
</script>
<style></style>
依賴收集流程:
從中我們可以發(fā)現,renderWatch是有收集 Dep(obj) 和 Dep(Obj.a) 的,但是當我們改變Obj的時候,并沒有觸發(fā)視圖的更新。因為我們在改變obj的值的時候,并沒有去觸發(fā)Dep(obj)。
產生問題的本質原因:
1、vue會在state.js文件的initData的方法中,將data屬性中的每一個key都變成響應式屬性。
2、視圖在渲染過程中,會將renderWatcher收集到用到的值的dep中,方便依賴更新(不懂的在回過去看一下依賴收集流程)
3、當你額外添加一個屬性的時候,該屬性并不是響應式屬性。
那如何去改變:
addObjB () {
// this.obj.b = 'obj.b'
this.$set(this.obj, 'b', 'obj.b')
console.log(this.obj)
}
總結
這篇文章是年度總結的開篇,后續(xù)會繼續(xù)總結初始化部分、render部分和patch部分。希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對我們網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!
上一篇:Node.js創(chuàng)建一個Express服務的方法詳解
欄 目:JavaScript
下一篇:Vue前端項目部署IIS的實現
本文標題:vue實現數據控制視圖的原理解析
本文地址:http://www.jygsgssxh.com/a1/JavaScript/9286.html
您可能感興趣的文章
- 04-02java后端代碼分頁 java后端實現分頁page
- 01-10Echarts實現單條折線可拖拽效果
- 01-10在Vue項目中使用Typescript的實現
- 01-10js實現上傳圖片并顯示圖片名稱
- 01-10Vue中使用Lodop插件實現打印功能的簡單方法
- 01-10echarts實現折線圖的拖拽效果
- 01-10js數據類型轉換與流程控制操作實例分析
- 01-10d3.js實現圖形縮放平移
- 01-10小程序簡單兩欄瀑布流效果的實現
- 01-10H5實現手機拍照和選擇上傳功能


閱讀排行
本欄相關
- 04-02javascript點線,點線的代碼
- 04-02javascript潛力,javascript強大嗎
- 04-02javascript替換字符串,js字符串的替換
- 04-02javascript移出,js 移入移出
- 04-02包含javascript舍的詞條
- 04-02javascript并行,深入理解并行編程 豆瓣
- 04-02javascript匿名,js匿名方法
- 04-02javascript警報,JavaScript警告
- 04-02javascript遮蓋,JavaScript遮蓋PC端頁面
- 04-02javascript前身,javascript的前身
隨機閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05dedecms(織夢)副欄目數量限制代碼修改
- 01-11ajax實現頁面的局部加載
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實例總結


