Vue.js指令是指帶有特殊前綴“v-”的HTML屬性,它綁定一個表達式愁铺,并將一些特性應用到DOM上。
5.1基本指令
5.1.1 v-cloak
v-clock不需要表達式平酿,它會在Vue實例結束編譯時從綁定的HTML元素上移除断凶,經(jīng)常和CSS的display:none配合使用:
<div id="app” v-clock>
? ? {{message}}
</div>
<script>
var app? = new Vue({
? ? el:'#app',
? ? data:{
? ? ? ? message:'這是一段文本‘
? ? }
?})
</script>
這時雖然已經(jīng)加了指令v-cloak,但其實并沒有起到任何作用报腔,當網(wǎng)速較慢株搔、Vue.js文件還沒起加載完畢時,在頁面上會顯示{{message}}的字樣纯蛾,直到Vue創(chuàng)建實例纤房、編譯模板時,DOM才會被替換翻诉,所以這個過程屏幕是有閃動的炮姨。只有加一句CSS就可以解決這個問題了:
[v-cloak]{
? ? display:none;
}
在一般情況下。v-cloak是一個解決初始化慢導致頁面閃動的最佳實踐碰煌,對于簡單的項目很實用舒岸,但是在具有工程化的項目里,比如后面我們將要學習的webpack和vue-router時拄查,項目的HTML結構只有一個空的div吁津,剩余的內(nèi)容都是由路由去掛載不同組件完成的,所以不再需要v-cloak堕扶。
5.1.2 v-once
v-once也是一個不需要表達式的指令碍脏,作用是定義它的元素或組件只渲染一次,包括元素或組件的所有子節(jié)點稍算。首次渲染后典尾,不再隨數(shù)據(jù)的變化重新渲染,將被視為靜態(tài)內(nèi)容糊探,例如:
<div id="app">
? ? <span v-once>{{message}}</span>
? ? <div v-once>
? ? ? ? <span>{{message}}</span>
? ? </div>
<div>
<script>
var app = new Vue({
? ? el:'#app',
? ? data:{
? ? ? ? message:'這是一段文本’
? ? }
})
</script>
v-once在業(yè)務中很少使用钾埂,當你需要進一步優(yōu)化性能上時河闰,可能會用到。
5.2條件渲染指令
5.2.1 v-if褥紫、v-else-if姜性、v-else
? ? 與JavaScript的條件語句if、else髓考、else if類似部念。?
Vue在渲染元素時,會盡可能地復用已有的元素而非重新渲染氨菇,比如下面這個示例就不會重新渲染:
<div id="app">
? ? <template v-if="type==='name'">
? ? ? <label>用戶名:</label>
? ? ? <input placeholder="輸入用戶名“/>
</template>
? ? <template v-else>
? ? ? <label>郵箱:</label>
? ? ? <input placeholder="輸入郵箱"/>
</template>
? ? <button @click="handleToggleCick">切換輸入類型</button>
?</div>
<script>
var app = new Vue({
? ? el:'#app',
? ? data:{
? ? ? tyle:'name'
},
methods:{
? ? ? handleToggleClick:function(){
? ? ? ? this.type=this.type==='name'?'mail':'name';
? ? }
? }
})
</script>
在上述代碼中儡炼,點擊切換按鈕后,會發(fā)現(xiàn)input里面的值是不會發(fā)生改變的查蓉,說明input被復用了乌询。顯然我們是不希望這么做的,因此這里介紹一下Vue.js提供的key屬性豌研。
在上述代碼中妹田,添加
……
<input placeholder="輸入用戶名" key="name-input"/>
……
<input placeholder="輸入郵箱" key="mail-input"/>
……
給兩個<input>元素都增加key后,就不會復用了聂沙,切換類型時鍵入的內(nèi)容也會被刪除秆麸,不過label元素仍然是復用的,因為沒有添加key屬性及汉。
5.2.2 v-show
? ? ?v-show與v-if的用法基本一致沮趣,只不過v-show是改變元素的CSS屬性display。當v-show表達式的值為false時坷随,元素隱藏房铭,查看DOM結構會看到該元素加載了內(nèi)聯(lián)樣式。
tips:v-show不能在<tempate>中使用温眉。
相比之下缸匪,v-if更適合條件不經(jīng)常使用的場景,因為它切換開銷相對較大类溢,而v-show適用于頻繁切換條件凌蔬。
5.3列表渲染指令v-for
5.3.1基本用法
當需要將一個數(shù)組便利或枚舉一個對象循環(huán)顯示時,就會用到列表渲染指令v-for闯冷,它的表達式需結合in來使用砂心,類似item in items的形式,看下面的示例:
<div id="#app">
? <ul>
? ? ?<li v-for="book in books">{{book.name}}<.li>
? <ul>
</div>
<script>
? ?var app = new Vue({
? ? el:'#app',
? ? data:{
? ? books:[
? ? ? {name,'《Vue.js實戰(zhàn)》'},
? ? ? {name:'《兄弟蛇耀,整理不易》'},
? ? ? {name:'《可否點個贊辩诞,加個喜歡》'}
? ? ]
? }
?})
</script>
v-for表達式支持一個可選參數(shù)作為當前項的索引,例如
……
<li v-for="(book,index) in books">{{index+1}}纺涤、{{book.name}}</li>
……
tips:分隔符in前的語句使用括號译暂,如果你使用過vue.js 1.x的版本抠忘,這里的index也可以由內(nèi)置的$index代替,不過在2.x里取消了該用法外永。
v-for還可以便利對象屬性崎脉,在便利對象屬性時,有兩個可選參數(shù)伯顶,分別是鍵名和索引:
<div id="app">
? <ul>
? ? ?<li v-for="(value,index,key) in user">
? ? {{index}}-{{key}}-{{value}}
? ? </li>
? </ul>
</div>
<script>
? var app = new Vue({
? ? el:'#app',
? ? data:{
? ? ? user:{
? ? ? ? name:'學習使我充實',
? ? ? ? again:'點贊讓我快樂',
? ? ? ? answer:'啊哈哈'
? ? ? }
? ? }
? })
<script>
渲染后的結果為:
·0-name:學習使我充實
·1-again:點贊讓我快樂
·2-answer:啊哈哈
v-for還可以迭代整數(shù):
<div id="app">
<span v-for="n in 10">{{n}}</span>
</div>
<script>
var app = new Vue({
el:'#app',
})
</script>
渲染后的結果為:1 2 3 4 5 6 7 8 9 10
5.3.2數(shù)組更新
Vue的核心是數(shù)據(jù)與視圖的雙向綁定荧嵌,當我們修改數(shù)組時,Vue會檢測到數(shù)據(jù)變化砾淌,所以用v-for渲染的視圖也會立即更新。Vue包含了一組觀察數(shù)組變異的方法谭网,使用它們改變數(shù)組也會觸發(fā)視圖更新:
? push()
? pop()
? shift()
? unshift()
? sort()
? reverse()
使用以上方法會改變被這些方法調(diào)用的原始數(shù)組汪厨,有些方法不會改變原始數(shù)組,例如:
? filter()
? concat()
? slice()
5.3.3過濾與排序
當你不想改變原數(shù)組愉择,想通過一個數(shù)組的副本來做過濾或排序的顯示時劫乱,可以使用計算屬性來返回過濾或排序后的數(shù)組,例如:
<div id="app">
? <ul>
? ? <template v-for="book in filterBooks">
? ? ? <li>書名:{{book.name}}</li>
? ? ? <li>作者:{{book.author}}</li>
? ? </template>
? </ul>
</div>
<script>
? ? var app = new Vue({
? ? ? el:'#app',
? ? ? data:{
? ? ? {name:'vue.js實戰(zhàn)'锥涕,author:'六個周'}衷戈,
? ? ? {name:'vue.js實戰(zhàn)進階',author:'七個周'}层坠,
? ? ? {name:'vue.js實戰(zhàn)高級版'殖妇,author:'八個周'}
},
computed:{
? ? ?filterBooks :function(){
? ? ? ?return this.books.filter(function(book){
? ? ? ? return book.name.match(/ vue.js/);
? ? });
? }
?}
})
</script>
上例是把書名中包含vus.js關鍵字的數(shù)據(jù)過濾出來破花,計算屬性filtersBook依賴books,但是不會修改books谦趣。
5.4方法與事件
5.4.1基本用法
在事件綁定上,類似原生JavaScript的onclick等寫法座每,也是在HTML上進行監(jiān)聽前鹅。例如,我們監(jiān)聽一個按鈕的點擊事件峭梳,設置一個計算器舰绘,每次點擊都加1:
<div? id="app">
? 點擊次數(shù):{{counter}}
? <button @click="counter++">+1<button>
</div>
<script>
? var app = new Vue({
? ? el:'#app',
? ? data:{
? ? counter:0;
? ? }
? })
</script>
@click的表達式可以直接使用JavaScript語句,也可也是一個在vue實例中methods選項內(nèi)的函數(shù)名葱椭,比如對上例進行擴展捂寿,再增加一個按鈕,點擊一次挫以,計數(shù)器加10:
<div id="app">
? 點擊次數(shù):{{counter}}
? <button @click="handleClick()">+1</button>
? <button @click="handleClick(10)+10</button>
</div>
<script>
? var app = new Vue({
? ? el:'#app',
? ? data:{
? ? counter:0;
? ? },
? methods:{
? ? handleClick:function(value){
? ? count = value||1;
? ? this.counter +=count;
? ?}
? }
?})
</script>
tips:@click調(diào)用的方法名后handleClick可以不跟括號“()”者蠕。
Vue提供了一個特殊變量$event,用于訪問原聲DOM事件,例如下面的實例可以阻止鏈接打開:
<div id="app">
<a href="www.lmzlyl.club"? @click="handleClick('禁止打開',$event)">打開鏈接</a>
</div>
<script>
var app = new Vue({
el:'#app',
methods:{
handleClick:function(msg,event){
event.preventDefault();
window.alert(msg);
}
}
})
</script>