模板語法
Vue.js使用了基于HTML的模板語法,允許開發(fā)者聲明式的將DOM綁定到底層vue實例的數(shù)據(jù),所有vuejs的模板都是合法的HTML,所以可以被遵循規(guī)范的瀏覽器和HTML解析器解析。
在底層實現(xiàn)上衣盾,vue將模板編譯成虛擬dom渲染函數(shù),結合響應系統(tǒng),vue可以智能的計算出最少需要渲染多少組件,并且把dom操作次數(shù)減到最小副女。
如果熟悉虛擬dom并且偏愛js的原始力量,也可以不使用模板蚣旱,碑幅,直接寫渲染 (render) 函數(shù),使用可選的 JSX 語法塞绿。
什么是虛擬dom
為何需要虛擬dom
dom是很大的沟涨,頁面元素非常龐大,而且頁面的性能也是由js引起的异吻,大部分都是由操作dom引起裹赴。
如果對前端的工作進行抽象的話,就是維護狀態(tài)和更新視圖,比如vue棋返,前端的框架主要發(fā)展方向就是解放DOM操作的復雜性延都。
如何理解虛擬dom
相對于dom對象,原生的js處理起來更快懊昨,而且處理更簡單窄潭,DOM 樹上的結構、屬性信息我們都可以很容易地用 JavaScript 對象表示出來:
var element = {
tagName: 'ul', // 節(jié)點標簽名
props: { // DOM的屬性酵颁,用一個對象存儲鍵值對
id: 'list'
},
children: [ // 該節(jié)點的子節(jié)點
{tagName: 'li', props: {class: 'item'}, children: ["Item 1"]},
{tagName: 'li', props: {class: 'item'}, children: ["Item 2"]},
{tagName: 'li', props: {class: 'item'}, children: ["Item 3"]},
]
}
//以上的react代碼轉化為html如下
<ul id='list'>
<li class='item'>Item 1</li>
<li class='item'>Item 2</li>
<li class='item'>Item 3</li>
</ul>
所以我們知道,dom樹信息是可以用js來表示的月帝,反過來躏惋,我們可以使用js對象來表示dom樹的結構,并且來構建一顆真正的dom樹嚷辅。
之前提到的簿姨,狀態(tài)變更→視圖重新渲染,這里有一點變化簸搞,js結構所表示的頁面dom信息結構扁位,狀態(tài)變更的時候,他會變化趁俊,但是此時真正的dom還沒有變化域仇。
但是新渲染的dom樹可以與之前的dom樹進行對比,記錄兩棵樹的差異寺擂,記錄的不同就是我們真正需要對dom的操作了暇务。把這些差異應用在真正的dom樹上,頁面就會改變了怔软。這樣就可以做到垦细,視圖的結構確實是全新渲染了,操作dom 的時候也是變更的不同的地方而已挡逼。
以上就是大致virtual dom的算法括改,
大致包括以下幾個步驟:
1.用js對象結構表示dom樹的結構,然后用這個js對象結構樹家坎,構建一個真正的dom樹嘱能,插入到文檔當中。
2.當狀態(tài)變更的時候乘盖,重新構造一顆新的js對象樹焰檩,然后新舊樹比較兩棵樹之間的差異,然后記錄下來订框。
3.將記錄下來的差異應用到步驟1所構建的真正的dom樹上析苫,視圖就更新了。
Virtual DOM 本質上就是在 JS 和 DOM 之間做了一個緩存●媒模可以類比 CPU 和硬盤国旷,既然硬盤這么慢,我們就在它們之間加個緩存:既然 DOM 這么慢茫死,我們就在它們 JS 和 DOM 之間加個緩存跪但。CPU(JS)只操作內存(Virtual DOM),最后的時候再把變更寫入硬盤(DOM)峦萎。
插值
文本
數(shù)據(jù)綁定最常見的形式就是使用“Mustache”語法 (雙大括號) 的文本插值:
<span>Message: {{ msg }}</span>
Mustache 標簽將會被替代為對應數(shù)據(jù)對象上 msg 屬性的值屡久。無論何時,綁定的數(shù)據(jù)對象上 msg 屬性發(fā)生了改變爱榔,插值處的內容都會更新被环。這是響應式的。
通過v-once
指令详幽,我們也可以進行一次性的插值筛欢,避免后續(xù) msg 值改變的時候,后續(xù)修改內容唇聘,但請留心這會影響到該節(jié)點上的其它數(shù)據(jù)綁定:
<span v-once>這個將不會改變: {{ msg }}</span>
原始HTML
雙大括號會將數(shù)據(jù)解釋為普通文本版姑,而非 HTML 代碼。為了輸出真正的 HTML迟郎,你需要使用 v-html
指令
雙大括號會將數(shù)據(jù)解釋為普通文本剥险,并非 HTML 代碼,如果我們需要輸出真正的HTML代碼谎亩,就需要使用v-html
指令炒嘲。
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
后者中,<span>
標簽的內容會被替換成屬性值rawHtml
匈庭,直接作為新的HTML
站點上動態(tài)渲染的任意 HTML 可能會非常危險夫凸,因為它很容易導致 XSS 攻擊。請只對可信內容使用 HTML 插值阱持,絕不要對用戶提供的內容使用插值夭拌。
特性
Mustache 語法不能作用在 HTML 特性上,遇到這種情況應該使用 v-bind 指令:
<div v-bind:id="dynamicId"></div>
這里的意思就是動態(tài)的綁定了id
<button v-bind:disabled="isButtonDisabled">Button</button>
如果 isButtonDisabled
的值是 null衷咽、undefined 或 false
鸽扁,則 disabled
特性甚至不會被包含在渲染出來的 <button>
元素中。
如果是true
镶骗,那么這個button
就是disable
桶现,不可點擊的。
使用js表達式
目前在模板中鼎姊,我們一直都只綁定簡單的屬性鍵值骡和。但實際上相赁,對于所有的數(shù)據(jù)綁定,Vue.js 都提供了完全的 JavaScript 表達式支持慰于。
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
這些表達式會在所屬 Vue 實例的數(shù)據(jù)作用域下作為 JavaScript 被解析钮科。有個限制就是,每個綁定都只能包含單個表達式婆赠,所以下面的例子都不會生效绵脯。
注意:
模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單休里,如 Math 和 Date或者用戶在data中定義的 蛆挫。你不應該在模板表達式中試圖訪問用戶定義的全局變量。
指令
指令是帶有v-
前綴的特殊特性的妙黍,指令特性的值璃吧,預期是單個的js表達式,除了v-for
指令废境,當其中表達式的值改變時,會產(chǎn)生連帶影響筒繁,響應式的作用于DOM中噩凹。
<p v-if="!seen">hahahahhaha</p>
export default {
name: 'App',
data(){
return{
seen:false
}
}
}
參數(shù)
一些指令能夠接收一個參數(shù),在指令的名稱后面用":"來表示毡咏,例如:
<a v-bind:href="url">...</a>
這里就能響應式的更新href中的url驮宴。
在這里 href 是參數(shù),告知 v-bind 指令將該元素的 href 特性與表達式 url 的值綁定呕缭。
另外一個是 v-on
指令堵泽,這是用來監(jiān)聽DOM事件的,
<p v-on:click="handleClick()">點擊</p>
export default {
name: 'App',
data(){
return{
}
},
methods:{
handleClick(){
console.log(1)
}
}
}
這里是在p標簽上綁定了click
事件恢总,事件的方法則卸載methods
中迎罗。
并且在這里,v-on
后面的參數(shù)就是事件名稱片仿,click纹安,mouseover
等。
修飾符
修飾符 (Modifiers) 是以半角句號 . 指明的特殊后綴砂豌,用于指出一個指令應該以特殊方式綁定厢岂。例如,.prevent
修飾符告訴v-on
指令對于觸發(fā)的事件調用 event.preventDefault()
:
還有在按鍵事件中會用到阳距,keyup.center
這樣的修飾符告訴按鍵按下的是center鍵塔粒,也是對事件的一個補充。
<input type="text" @keyup.enter="test()">
在接下來對 v-on
和 v-for
等功能的探索中筐摘,你會看到修飾符的其它例子卒茬。
縮寫
v-bind的縮寫
<!-- 完整語法 -->
<a v-bind:href="url">...</a>
<!-- 縮寫 -->
<a :href="url">...</a>
v-on的縮寫
<!-- 完整語法 -->
<a v-on:click="doSomething">...</a>
<!-- 縮寫 -->
<a @click="doSomething">...</a>