第三章 指令
指令:是特殊的帶有前綴v- 的特性。指令的值限定爲綁定表達式,指令的職責就是當其表達式的值改變時把某些特殊的行爲應用在DOM上
一. 內部指令
.內置指令
1.v-if
根據表達式的值在DOM中生成或移除一個元素。當賦值爲false
則對應的元素會從DOM中移除,否則對應元素的一個克隆將被重新插入DOM中。(這也是v-if
和v-show
的一個區別)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-if</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<!--v-if中的內容爲true則顯示,false則隱藏-->
<p v-if="beautiful"><span>beautiful girl</span></p>
</div>
<script>
new Vue({
el:'#box',
data:{
beautiful:false,
}
})
</script>
</body>
</html>
v-if是一個指令,需要將它添加到一個元素上,但如果想切換多個元素,則可以把元素當做包裝元素,並在其上使用v-if,最終的渲染結果不會包含template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-if</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<template v-if="ok">
<h1>happly good day</h1>
<p>chapter01</p>
<p>chapter02</p>
</template>
</div>
<script>
new Vue({
el:'#box',
data:{
ok:true
}
})
</script>
</body>
</html>
2.v-show
根據表達式的值來顯示或隱藏HTML元素。當v-show爲false
,元素將被隱藏。查看DOM
時會發現元素上多了一個內聯樣式style="display:none"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-show</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<!--條件爲TRUE,輸出-->
<h1 v-show="ok">Hello!</h1>
<!--條件爲false,不輸出-->
<h1 v-show="error">false!</h1>
<!--條件爲TRUE,輸出-->
<h1 v-show="10>5">10大於5,輸出!</h1>
<!-- 條件爲false,不輸出-->
<h1 v-show="2>10">不大於10,不輸出!</h1>
</div>
<script>
new Vue({
el:'#box',
data:{
ok: true,
error: false
}
})
</script>
</body>
</html>
注意:v-show不支持<template>
一般來說,v-if
有更高的切換消耗,而v-show
有更高的初始渲染消耗。因此需要頻繁切換,則使用v-show
較好;若在運行時條件不大可能改變則使用v-if
較好。
3.v-else
:使用它必須跟在v-if/v-show
充當else功能。(其實就是在v-if後面和if else條件判斷的作用是一樣的)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-else</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<h1 v-if="ok">Hello!</h1>
<h1 v-else="ok">false!</h1>
</div>
<script>
new Vue({
el:'#box',
data:{
ok: false,
}
})
</script>
</body>
</html>
4.v-model
指令用來在input、select、text、checkbox、radio
等表單控件上創建雙向數據綁定。根據控件類型v-model
自動選取正確的方法更新元素。v-model
是語法糖,在用戶輸入事件中更新數據,以及特別處理一些極端例子。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-model </title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<form action="">
<label for="name">姓名:</label>
<input type="text" v-model="name" id="name">
<br>
性別:
<input type="radio" id="man" value="One" v-model="sex">
<label for="man">男</label>
<input type="radio" id="male" value="Tow" v-model="sex">
<label for="male">女</label>
<br>
興趣:
<label for="book">閱讀</label>
<input type="checkbox" id="book" value="book" v-model="interest">
<label for="swim">游泳</label>
<input type="checkbox" id="swim" value="swim" v-model="interest">
<label for="game">遊戲</label>
<input type="checkbox" id="game" value="game" v-model="interest">
<label for="song">唱歌</label>
<input type="checkbox" id="song" value="song" v-model="interest">
<br>
<label for="identify">身份:</label>
<select name="" id="identify">
<option value="teacher" selected>教師</option>
<option value="doctor">醫生</option>
<option value="lawyer">律師</option>
</select>
</form>
</div>
<script>
new Vue({
el:'#box',
data:{
name:'',
sex:'',
interest:[],
identify:''
}
})
</script>
</body>
</html>
v-model指令後面還可以添加多個參數(number、lazy、debounce)<template>
①number
如果想將用戶的輸入自動轉換爲Number類型(如果原值的轉換結果爲NaN,則返回原值),
可以添加一個number特性。
②lazy
在默認情況下,v-model在input事件中同步輸入框的值和數據,我們可以添加一個lazy特性,從而將數據改到在change事件中發生。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-model </title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<input type="text" v-model.lazy="msg" >
<br>
{{msg}}
</div>
<script>
new Vue({
el:'#box',
data:{
msg:'內容是在change事件之後才改變的'
}
})
</script>
</body>
</html>
③debounce
設置一個最小的延時,在每次敲擊之後延時同步輸入框的值和數據。如果 每次更新都要進行高耗操作(如在input中輸入內容時隨時發送ajax請求)則他較爲有用
5.v-for
基於源數據重複渲染元素。我們也可以使用$index
來呈現相對應的數組索引。
這裏的寫法在vue2.0中不再適用所以不寫出來了,學習v-for參考官網列表渲染
vue包裝了被觀察數組的變異方法,他們能觸發視圖更新
變異方法 (mutation method):
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
非變異 (non-mutating method) 方法,例如 filter()、concat() 和 slice() 。它們不會改變原始數組,而總是返回一個新數組。當使用非變異方法時,可以用新數組替換舊數組。
v-for提供的內置過濾器:
Vue.extend
Vue.nextTick
Vue.set
Vue.delete
Vue.directive
Vue.filter
Vue.component
Vue.use
Vue.mixin
Vue.compile
Vue.observable
Vue.version
6.v-text
可以更新元素的textContent
7.v-html
可以更新元素的innerHTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-text</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<template>
<div>
<p v-text="hello"></p>
<p v-html="hello"></p>
{{ num }}<br>
{{ status ? 'success' : 'fail' }}
</div>
</template>
</div>
<script>
new Vue({
el:'#box',
data:{
hello: '<span>Hello World</span>',
num: 1,
status: true
}
})
</script>
</body>
</html>
8.v-bind
用於響應更新HTML特性,將一個或多個attribute,或者一個組件prop動態綁定到表達式
v-bind簡寫爲冒號:
<img v-bind:src="" alt="" >
<img :src="" alt="">
在綁定class或style時,支持其他類型的值,如數組或對象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-text</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<style>
.A{
font-size: 1.2rem;
color: #fff;
background-color: #cccccc;
}
.classB{
font-weight: bold;
border-bottom: 1px solid #666666;
}
</style>
</head>
<body>
<div id="box">
<p :class="[classA,{classB:isB,classC:isC}]">Hello World</p>
</div>
<script>
new Vue({
el:'#box',
data:{
classA:'A',
isB:true,
isC:false
}
})
</script>
</body>
</html>
沒有參數時,可以綁定到一個對象。注意,此時class和style不支持數組和對象。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>指令v-bind</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<style>
#idName{
color: #fff;
background-color: #317ee7;
font-weight: bold;
}
</style>
</head>
<body>
<div id="box">
<div v-bind="{id:someProp,'OTHERAttr':otherProp}">HelloWorld</div>
</div>
<script>
new Vue({
el:'#box',
data:{
someProp:'idName',
otherProp:'prop',
}
})
</script>
</body>
</html>
在綁定prop時,prop必須在子組件中聲明。可以用修飾符指定不同的綁定類型。
修飾符爲: .sync——雙向綁定,只用於prop綁定。
.once——單次綁定,只用於prop綁定。
.camel——將綁定的特性名字轉換回駝峯命名。只能用於普通HTML特性的綁定,通常用於綁定用駝峯命名的svg特性。(比如viewBox)
<div id="box">
<div v-bind="{id:someProp,'OTHERAttr':otherProp}">HelloWorld</div>
<!--prop綁定,“prop”必須在m-component組件內聲明-->
<my-component :prop="someThing"></my-component>
<!--雙向prop綁定-->
<my-component :prop.sync="someThing"></my-component>
<!--單向prop綁定-->
<my-component :prop.once="someThing"></my-component>
</div>
9.v-on
用於綁定事件監聽器。事件類型由參數指定;表達式可以是一個方法的名字或者一個內聯語句;如果沒有修飾符,可以省略。
使用在普通元素上時,只能監聽原生DOM事件;使用在自定義元素組件上時,也可以監聽子組件觸發的自定義事件。
在監聽原生DOM事件時,如果只定義一個參數,DOM event
爲事件的唯一參數;如果在內聯語句處理器中訪問原生DOM事件,則可以用特殊變量 $event
把他傳入方法。
10.v-ref
在父組件上註冊一個子組件的索引,便於直接訪問。可以通過父組件的$refs
對象訪問子組件。
11.v-el
爲DOM元素註冊一個索引,方便通過所屬實例$refs
訪問這個元素。可以用v-el:some-el
設置this.$els.someEl
12.v-pre編譯時跳過當前元素和他的子元素。可以用來顯示原始Mustache標籤。跳過大量沒有指令的節點會加快編譯。
13.v-cloak
保持在元素上直到關聯實例結束編譯。
二.自定義指令
1.基礎
1-1鉤子函數
update
——在bind之後立刻以初始值爲參數第一次調用,之後每次綁定值變化時調用,參數爲新值與舊值。
unbind
——只調用一次,在指令從元素上解綁時調用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定義指令</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id="box">
<div v-my-directive="someValue"></div>
</div>
<script>
new Vue({
el:'#box',
data:{
}
})
Vue.directive('my-directive',{
bind:function () {
// 準備工作
},
update:function (newValue,oldValue) {
// 值更新時的工作
// 也會以初始值爲參數調用一次
},
unbind:function () {
// 清理工作
}
})
</script>
</body>
</html>
1-2.指令實例屬性
所有的鉤子函數都將被複制到實際的指令對象中,在鉤子內this指向這個指令對象。這個對象暴露了一些有用的屬性。
屬性:el——指令綁定的元素
vm——擁有該指令的上下文ViewModel
expression——指令的表達式,不包括參數和過濾器
arg——指令的參數
name——指令的名字,不包含前綴
modifiers——一個對象,包含指令的修飾符
descriptor——一個對象,包含指令的解析結果
1-3.對象字面量
如果指令需要多個值,則可以傳入一個JavaScript對象字面量。
1-4字面修飾符
1-5元素指令
2.高級選項
params
deep
twoWay
acceptStatement
Terminal
priority
3.內部指令解析
4.常見問題解析