阻止同步
使用 Object.freeze(),這會(huì)阻止修改現(xiàn)有的屬性搁凸,也意味著響應(yīng)系統(tǒng)無(wú)法再追蹤變化辛掠。
var obj = {
foo: 'bar'
}
Object.freeze(obj)
new Vue({
el: '#app',
data: obj
})
<div id="app">
<p>{{ foo }}</p>
<!-- 這里的 `foo` 不會(huì)更新! -->
<button v-on:click="foo = 'baz'">Change it</button>
</div>
Vue實(shí)例屬性和方法
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一個(gè)實(shí)例方法
vm.$watch('a', function (newValue, oldValue) {
// 這個(gè)回調(diào)將在 `vm.a` 改變后調(diào)用
})
實(shí)例生命周期
實(shí)例生命周期 Demo
實(shí)例被創(chuàng)建
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 實(shí)例
console.log('a is: ' + this.a)
}
})
語(yǔ)法
-
動(dòng)態(tài)更新: {{ msg }}
- 為增加屬性 v-once 將插入不更新數(shù)據(jù)
<span v-once>這個(gè)將不會(huì)改變: {{ msg }}</span>
-
HTML文本: 為標(biāo)簽增加屬性 v-html="實(shí)例的vue數(shù)據(jù)"
<p>Using v-html directive: <span v-html="rawHtml"></span></p> <!-- 注意褐隆,你不能使用 v-html 來(lái)復(fù)合局部模板 -->
注意:你的站點(diǎn)上動(dòng)態(tài)渲染的任意 HTML 可能會(huì)非常危險(xiǎn)侦副,因?yàn)樗苋菀讓?dǎo)致 XSS 攻擊侦锯。請(qǐng)只對(duì)可信內(nèi)容使用 HTML 插值,絕不要對(duì)用戶提供的內(nèi)容使用插值秦驯。
-
表達(dá)式
- Vue.js 都提供了完全的 JavaScript 表達(dá)式支持尺碰。有個(gè)限制就是,每個(gè)綁定都只能包含單個(gè)表達(dá)式
<!-- 這是語(yǔ)句,不是表達(dá)式 --> {{ var a = 1 }} <!-- 流控制也不會(huì)生效亲桥,請(qǐng)使用三元表達(dá)式 --> {{ if (ok) { return message } }}
模板表達(dá)式都被放在沙盒中洛心,只能訪問(wèn)全局變量的一個(gè)白名單,如 Math 和 Date 题篷。你不應(yīng)該在模板表達(dá)式中試圖訪問(wèn)用戶定義的全局變量词身。
-
修飾符
修飾符 (Modifiers) 是以半角句號(hào) . 指明的特殊后綴,用于指出一個(gè)指令應(yīng)該以特殊方式綁定番枚。例如法严,.prevent 修飾符告訴 v-on 指令對(duì)于觸發(fā)的事件調(diào)用 event.preventDefault():
<form v-on:submit.prevent="onSubmit">...</form>
-
縮寫
v-bind:data 可以縮寫為:data v-on:click可以縮寫為@click
計(jì)算屬性
模板內(nèi)的表達(dá)式非常便利,但是設(shè)計(jì)它們的初衷是用于簡(jiǎn)單運(yùn)算的葫笼。在模板中放入太多的邏輯會(huì)讓模板過(guò)重且難以維護(hù)深啤。
所以我們會(huì)用到計(jì)算屬性
Example :
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 計(jì)算屬性的 getter
reversedMessage: function () {
// `this` 指向 vm 實(shí)例
return this.message.split('').reverse().join('')
}
}
})
提醒 : 計(jì)算屬性的值總是基于被計(jì)算屬性的值,即:當(dāng)修改vm.message的值時(shí) vm.reversedMessage 輸出的值也會(huì)被修改
計(jì)算屬性緩存 vs 方法
我們可以將同一函數(shù)定義為一個(gè)方法而不是一個(gè)計(jì)算屬性渔欢。兩種方式的最終結(jié)果確實(shí)是完全相同的墓塌。然而,不同的是<b>計(jì)算屬性是基于它們的依賴進(jìn)行緩存的</b>奥额。只在相關(guān)依賴發(fā)生改變時(shí)它們才會(huì)重新求值苫幢。這就意味著只要 message 還沒(méi)有發(fā)生改變,多次訪問(wèn) reversedMessage 計(jì)算屬性會(huì)立即返回之前的計(jì)算結(jié)果垫挨,而不必再次執(zhí)行函數(shù)韩肝。
總結(jié) : 計(jì)算屬性只有具有響應(yīng)式依賴的變量(實(shí)例對(duì)象中的data)才會(huì)動(dòng)態(tài)更新,當(dāng)計(jì)算屬性為以下Demo時(shí)不會(huì)被動(dòng)態(tài)修改,methods則相反九榔。所以計(jì)算屬性更節(jié)省資源哀峻,如果你不希望有緩存,請(qǐng)用方法來(lái)替換計(jì)算屬性哲泊。
computed: {
now: function () {
return Date.now()
//Date.now不是一個(gè)響應(yīng)式依賴對(duì)象
}
}
偵聽(tīng)屬性
Vue 提供了一種更通用的方式來(lái)觀察和響應(yīng) Vue 實(shí)例上的數(shù)據(jù)變動(dòng):偵聽(tīng)屬性剩蟀。當(dāng)你有一些數(shù)據(jù)需要隨著其它數(shù)據(jù)變動(dòng)而變動(dòng)時(shí),你很容易濫用 watch切威,通常更好的做法是使用計(jì)算屬性而不是命令式的 watch 回調(diào)育特。
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
//偵聽(tīng)屬性 實(shí)時(shí)響應(yīng)Vue實(shí)例的數(shù)據(jù)變動(dòng)
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})
計(jì)算屬性的 setter
計(jì)算屬性默認(rèn)只有 getter ,不過(guò)在需要時(shí)你也可以提供一個(gè) setter :
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
//現(xiàn)在再運(yùn)行 vm.fullName = 'John Doe' 時(shí)先朦,setter 會(huì)被調(diào)用缰冤,vm.firstName 和 vm.lastName 也會(huì)相應(yīng)地被更新。
綁定Html Class
我們可以傳給元素一個(gè)v-bind:class的對(duì)象以動(dòng)態(tài)的切換class喳魏,且v-bind:class與class可以共存
v-bind:class的格式是 {className1:boolean,className2:boolean,...}
DEMO - CSS Bind
<style>
.base{
/* StyleBody */
}
.active{
/* StyleBody */
}
.model{
/* StyleBody */
}
</style>
<div class="base" v-bind:class="{ active: isActive , model: isModel}"></div>
new Vue({
el:"#假定的父級(jí)元素ID",
data:{
isActive:true;
isModel:false;
}
})
最后DIV會(huì)被渲染為如下樣式棉浸,且當(dāng)改變Vue實(shí)例對(duì)象中的數(shù)據(jù)時(shí)該DIV樣式會(huì)對(duì)應(yīng)被改變
<div class="base active"></div>
注意:這種動(dòng)態(tài)改變樣式的方式還可以用計(jì)算屬性實(shí)現(xiàn),同樣也是一個(gè)常用且強(qiáng)大的模式
另一種實(shí)現(xiàn)方式
DEMO
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
綁定CSS - 數(shù)組語(yǔ)法
我們同樣可以為v:bind-class傳一個(gè)數(shù)組刺彩,以應(yīng)用一個(gè)class列表
<div v-bind:class="[activeClass, errorClass]"></div>
對(duì)應(yīng)Vue實(shí)例
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
你也可以根據(jù)需要來(lái)修改數(shù)組的表達(dá)形式迷郑,其中可以包括三元表達(dá)式:
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
但是當(dāng)多個(gè)元素都需要做判斷的時(shí)候枝恋,這樣的寫法顯得非常的繁瑣,所以在數(shù)組語(yǔ)法中也可以使用對(duì)象語(yǔ)法:
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
綁定內(nèi)聯(lián)樣式
v-bind:style 的對(duì)象語(yǔ)法十分直觀——看著非常像 CSS嗡害,但其實(shí)是一個(gè) JavaScript 對(duì)象鼓择。CSS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用單引號(hào)括起來(lái)) 來(lái)命名:
DEMO
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
同樣的就漾,你可以直接綁定Style對(duì)象(Object)
DEMO
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
Style樣式也同樣擁有數(shù)組語(yǔ)法
DEMO
<div v-bind:style="[baseStyles, overridingStyles]"></div>
注意:部分樣式需要添加瀏覽器內(nèi)核標(biāo)識(shí),如transform念搬,Vue.js會(huì)自動(dòng)偵聽(tīng)并添加
條件語(yǔ)句
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
<!-- v-else 綁定元素需要緊跟在v-if元素或v-else-if后 -->
Tips:如果你想使用 v-if 隱藏多個(gè)元素抑堡,不妨嘗試一下template 參考此處
v-else-if (version 2.1.0)
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
用 key 管理可復(fù)用的元素
Vue 會(huì)盡可能高效地渲染元素,通常會(huì)復(fù)用已有元素而不是從頭開(kāi)始渲染朗徊。這么做除了使 Vue 變得非呈籽快之外,還有其它一些好處爷恳。例如有缆,如果你允許用戶在不同的登錄方式之間切換:
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
那么在上面的代碼中切換 loginType 將不會(huì)清除用戶已經(jīng)輸入的內(nèi)容。因?yàn)閮蓚€(gè)模板使用了相同的元素温亲,<input>
不會(huì)被替換掉——僅僅是替換了它的 placeholder棚壁。
但是,這樣也不總是符合實(shí)際需求栈虚,所以 Vue 為你提供了一種方式來(lái)表達(dá)“這兩個(gè)元素是完全獨(dú)立的袖外,不要復(fù)用它們”。只需添加一個(gè)具有唯一值的 key 屬性即可:
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
這樣魂务,添加了key屬性以后曼验,vue會(huì)重新渲染元素而不是修改元素,但是請(qǐng)注意<label>
元素仍然會(huì)被高效使用
v-show
另一個(gè)用于根據(jù)條件展示元素的選項(xiàng)是 v-show 指令粘姜。用法大致一樣:
<h1 v-show="ok">Hello!</h1>
不同的是帶有 v-show 的元素始終會(huì)被渲染并保留在 DOM 中鬓照。v-show 只是簡(jiǎn)單地切換元素的 CSS 屬性 display。
注意孤紧,v-show 不支持
<template>
元素豺裆,也不支持 v-else。
v-if vs v-show
v-if 是“真正”的條件渲染坛芽,因?yàn)樗鼤?huì)確保在切換過(guò)程中條件塊內(nèi)的事件監(jiān)聽(tīng)器和子組件適當(dāng)?shù)乇讳N毀和重建留储。
v-if 也是惰性的:如果在初始渲染時(shí)條件為假,則什么也不做——直到條件第一次變?yōu)檎鏁r(shí)咙轩,才會(huì)開(kāi)始渲染條件塊获讳。
相比之下,v-show 就簡(jiǎn)單得多——不管初始條件是什么活喊,元素總是會(huì)被渲染丐膝,并且只是簡(jiǎn)單地基于 CSS 進(jìn)行切換。
一般來(lái)說(shuō),v-if 有更高的切換開(kāi)銷帅矗,而 v-show 有更高的初始渲染開(kāi)銷偎肃。因此,如果需要非常頻繁地切換浑此,則使用 v-show 較好累颂;如果在運(yùn)行時(shí)條件很少改變,則使用 v-if 較好凛俱。
注意 :不推薦同時(shí)使用 v-if 和 v-for 詳細(xì)信息
列表渲染
v-for
不做詳細(xì)介紹
DEMO
<ul id="example-1">
<!-- 此處可以使用 of 代替 in -->
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
如果你需要使用到for循環(huán)中的索引值
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
一個(gè)對(duì)象的 v-for
Vue同樣可以使用v-for迭代對(duì)象
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
}
})
這種方式只會(huì)輸出對(duì)應(yīng)Map中的Value紊馏,這可能不能滿足復(fù)雜的業(yè)務(wù)需求
Out Key,Value
DEMO
<div v-for="(value, key) in object">
{{ key }}: {{ value }}
</div>
同樣的蒲犬,括號(hào)里面可以提供第三個(gè)參數(shù)index
注意 : 除了value以外朱监,key和index的名字是固定的
等同于v-if的默認(rèn)高效原則,v-for會(huì)優(yōu)先修改元素而不是重新渲染元素原叮,如果你想讓每個(gè)元素保持獨(dú)立赫编,同樣可以綁定key屬性 v-bind:key="key"