虛擬dom和diff算法

vue2.0加入了virtual dom,有點向react靠攏的意思。vue的diff位於patch.js文件中,複雜度爲O(n)。 瞭解diff過程,我們先從虛擬dom開始。

1. 虛擬dom是什麼?

虛擬dom( virtual dom )它是一個Object對象模型,用來模擬真實dom節點的結構。

2. diff算法是什麼?

diff算法是比較兩個文件的差異,並將兩個文件不同之處,將這個不同之處生成一個補丁對象(patch)
diff算法來源後端
前端將其應用於虛擬dom的diff算法
vue中將 虛擬dom的diff算法放在了 patch.js文件中
使用js來進行兩個對象的比較( vdom 對象模型)
diff算法是同級比較
給每一個層級打一個標記,這個標記是一個數字( 這個數字就是 key )

3. diff算法運行結束之後,返回什麼?

diff算法會返回一個補丁對象patch

4. 虛擬dom的使用基本流程

1.獲取數據( ajax fetch )


var data = {
id: 1,
name: 'csdn'
}
  1. 創建vdom
 <div class = "box">
        <ul>
          <li> {{ data.name }} </li>
        </ul>
      </div> 
  1. 通過render函數解析jsx,將其轉換成 vdom結構

	var vdom = {
			tag: 'div',
			attr: {
			className: 'box'
			},
			content: [
			{
			tag: 'ul',
			content: [
				{
			tag: 'li',
			content: data.name
				}
			]
		}
	]
}

  1. 將vdom渲染成真實dom
  2. 數據更改了, data.name = ‘gfly’
 data.name = 'gfly'

    vdom = {
      tag: 'div',
      attr: {
        className: 'box'
      },
      content: [
        {
          tag: 'ul',
          content: [
            {
              tag: 'li',
              content: data.name
            }
          ]
        }
      ]
    }
  1. 使用diff算法比對兩次vdom,生成patch對象

  2. 根據key將patch對象渲染到頁面中改變的結構上,而其他沒有改變的地方是不做任何修改的( 虛擬dom的惰性原則 )

注意:vue是一是MVVM框架,Vue高性能的原因之一就是vdom

5. 什麼是jsx?

jsx javascript + xml

6. 驗證 key

  • 列表循環一定加key
  • key最好是使用具有唯一標識性的 id

7. 爲什麼列表循環要加key ?

key是用來做標識的( 同級比較 )


<div id="app">
<ul>
<li v-for = " (item,index) in list" :key = "item.id">
<p> {{ item.text }} </p>
<div>
<button @click = "changeStyle"> 修改樣式 </button>
<button @click = "remove( index )">刪除 </button>
</div>
</li>
</ul>
</div>


new Vue({
	el: '#app',
	data: {
	list: [
		{
			id: 1,
			text: '敲代碼1'
		},
		{
			id: 2,
			text: '敲代碼2'
		}
	]
},
	methods: {
		changeStyle ( e ) {
		//這段代碼將來不要出現,
		// 理由: 我們應該避免操作真實dom
		e.target.parentNode.parentNode.style.background = 'red'
		},
	remove ( index ) {
		this.list.splice( index, 1 )
		}
	}
})


Vue有兩大特性

  1. 指令 – 用來操作dom

  2. 組件 – 組件是html css js 等的一個聚合體

  3. 爲什麼要使用組件?
    (1) 組件化
    a 將一個具備完整功能的項目的一部分進行多處使用
    b 加快項目的進度
    c 可以進行項目的複用
    (2) 要想實現組件化,那麼我們使用的這一部分就必須是完整的,我們把這個完整的整體就稱之爲組件
    (3) 插件: index.html img css js
    (4) 如果能將 html css js img 等多個部分放在一起,那該有多好,vue將這個聚合體的文件稱之爲,單文件組件( xx.vue )

  4. 基礎的組件創建

    1. 全局註冊

<div id="app">
	<Father></Father>
</div>
<div id="root">
	<Father></Father>
</div>

var Hello = Vue.extend({
	template: '<div> 這裏是father組件 </div>'
}) //VueComponent( option )
	Vue.component( 'Father', Hello )
	new Vue({
	el: '#app'
})
	new Vue({
	el: '#root'
})
  1. 局部註冊
<div id="app">
	<ppk></ppk>
</div>
<div id="root">
	<ppk></ppk>
</div>

var Hello = Vue.extend({
	template: '<div> hello </div>'
})
	new Vue({
	el: '#app',
	components: {
// key: value key是組件名稱 value是組件配置項
// 'ppk': Hello,
	'ppk': Hello
	}
})
new Vue({
	el: '#root'
})
  1. 必須掌握的
    1. vue是如何擴展組件的?
    2. vue爲什麼要以標籤的形式使用組件
    3. 組件使用爲何要註冊
  2. 組件的一些特殊使用規則 【 is 規則】

is規則
ul>li ol>li table>tr>td select>option
如上直屬父子級如果直接組件以標籤化形式使用,那麼就會出現bug
解決: 使用is規則: 通過is屬性來綁定一個組件

<tr is = "Hello"></tr>

<div id="app">
	<table>
		<tr>
			<td>1</td>
			<td>2</td>
			<td>3</td>
		</tr>
		<tr is = "Hello"></tr>
	</table>
</div>

Vue.component('Hello',{
	template: '<tr> <td> 4 </td> <td> 2 </td><td> 3 </td></tr>'
})
new Vue({
	el: '#app'
})

  1. 組件的template

template使用:

  1. 實例範圍內使用
    template中的內容被當做一個整體了,並且template標籤是不會解析到html結構中的
  2. 實例範圍外使用
    實例範圍外template標籤是不會被直接解析的
    組件要想使用template使用,我們採用第二種
    但是使用第二種template使用後,有個弊端,template標籤結構會在html文件中顯示
    解決:使用webpack、gulp等工具編譯,將來要用vue提供的單文件組件

<div id="app">
    <h3> 實例範圍內使用 </h3>
        <template>
        <div>
 <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
</ul>
</div>
	</template>
<h3> 使用 hello 組件</h3>
    <Hello></Hello>
</div>
    <h3> 實例範圍外使用 </h3>
<template id="hello">
    <div>
<ul>
    <li>1</li>
    <li>2</li>
</ul>
	</div>
</template>

Vue.component('Hello',{
template: '#hello'
})
new Vue({
el: '#app'
})

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章