在學習vue時,插值表達式和vue指令可謂是基礎中的基礎,這篇文章,就讓你徹底瞭解怎麼使用插值表達式和vue中所有指令的用法。
一、插值表達式:{{ }}
- 可以將vue中的數據填寫在插值表達式中
<div id="app">{{ title }}</div>
<script>
const vm = new Vue({
el:"#app",
data:{
title:"the first vue"
}
})
</script>
- 也可以直接填寫數值、數組、對象等。
<div id="app">{{ 123 }}</div>
- 可以填寫表達式,但是不能寫流程語句。
<div id="app">
{{ 100*2 }}
{{ 1 + 1 === 2 ? "是的" : "不是" }}
</div>
- 注意:儘量中間加上空格,否則遇到一個對象的時候,會報錯。也不能使用未聲明的變量。
<div id="app">{{{a:1}}}</div>
//Error compiling template
二、vue中的指令
1、v-pre
v-pre
:不使用vue語法進行渲染,跳過元素和他的子元素的編譯過成。
<div v-pre>{{ title }}</div>
// {{ title }}
2、v-cloak
v-cloak
:當元素在編譯時存在,當元素編譯完成後,該指令消失。通常解決首屏閃爍。
[v-cloak] {
display: none;
}
<div v-cloak>{{ title }}</div>
3、v-once
v-once
:只渲染一次,之後的重新渲染,元素及其所有的子節點將被視爲靜態內容並跳過。因爲它使用緩存中的值,不再使用vm中的值,數據也就不再變化。
<div v-once>{{ title }}</div>
4、v-html
-
v-html
:相當於innerHTML
。內容按普通 HTML 插入,不會作爲 Vue 模板進行編譯 。注意:小心XXS攻擊,在可信內容上使用v-html,拒絕用戶交互下使用該指令
<div v-html="title"></div> // the first vue {{ name }}
<script>
const vm = new Vue({
el:"#app",
data:{
title:"the first vue {{ name }}",
name:"lkx"
}
})
</script>
5、v-text
v-text
:相當於textContent
。
注意:v-text
會替換元素中所有的文本,插值表達式只替換自己,不會清空元素。優先級比插值表達式高。
<div v-text="title"></div>
<!-- 和下面的效果一樣 -->
<div>{{ title }}</div>
補充: dom.innerText
和dom.textContent
- 設置文本替換時,兩者都會把指定節點下的所有子節點也一併替換掉。
- innerText 受 CSS 樣式的影響,並且不會返回隱藏元素的文本,而textContent會。
- 由於 innerText 受 CSS 樣式的影響,它會觸發重排(reflow),但textContent 不會。
- textContent 會獲取所有元素的內容,包括
<script>
和<style>
元素,但innerText不會
6、v-if
7、v-else-if
8、v-else
-
v-if
:控制元素的顯示和隱藏,通過對元素的添加和刪除。可以作用在template上。 -
v-else-if
:控制元素顯示和隱藏。前一個兄弟元素必須有v-if
-
v-else
:前一個兄弟元素必須有v-if
或v-else-if
<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>
9、v-show
v-show
:控制標籤的顯示和隱藏,通過操作display:none|block
屬性控制顯示和隱藏,v-show對template標籤不起作用,顯而易見是因爲template標籤,沒有任何意義,也不會渲染到頁面中,只是爲了方便填寫指令出現的。
<div v-show="isShow">{{ title }}</div>
注意:v-if
是惰性的,如果在初始渲染時條件爲假,則什麼也不做,直到條件第一次變爲真時,纔會開始渲染條件塊。v-show
則不管初始條件是什麼,元素總是會被渲染,並且只是簡單地基於 CSS
進行切換。v-if
有更高的切換開銷,v-show
有更高的初始渲染開銷,如果需要頻繁切換,v-show
比較好,如果改變少,則v-if
更好。
10、v-bind
v-bind
:動態綁定一個或多個特性值,或用:
縮寫。:
後面的時參數,例如:v-bind:src="imgSrc"
,src
就是參數
<!-- 綁定一個屬性 -->
<img v-bind:src="imgSrc">
<!-- 動態特性名 (2.6.0+) -->
<button v-bind:[key]="value"></button>
<!-- 縮寫 -->
<img :src="imgSrc">
<!-- 動態特性名縮寫 (2.6.0+) -->
<button :[key]="value"></button>
<!-- 內聯字符串拼接 -->
<img :src="'/img/' + fileName">
<!-- 沒有參數,綁定一個對象,鍵值會變爲特性名和值 -->
<img v-bind="{src:'a.jpg'}>
使用v-bind
綁定class
和style
綁定class
:綁定class並非覆蓋原來的class,只是在原來的基礎上添加
- 對象語法:是否使用
red
類名,取決於isRed
變量的真假
<div v-bind:class="{ red: isRed }"></div>
- 數組語法:我們可以把一個數組傳給 v-bind:class,以應用一個 class 列表
<div v-bind:class="[classA, classB]"></div>
注意:
- 在數組語法中可以使用三元表達式來切換class
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
- 在數組語法中可以使用對象語法
<div v-bind:class="[classA, { classB: isB, classC: isC }]">
<div v-bind:class="classA" class="red">
- v-bind:class 可以與普通 class 共存
<div v-bind:class="classA" class="red">
綁定style
:
- 對象語法:看着比較像CSS,但其實是一個JavaScript對象
<div v-bind:style="{ fontSize: size + 'px' }"></div>
<script>
const vm = new Vue({
el:"#app",
data:{
size: 30
}
})
</script>
<!-- 等同於下面寫法 -->
<div v-bind:style="styleObject"></div>
<script>
const vm = new Vue({
el:"#app",
data:{
styleObject: {
fontSize: '13px'
}
}
})
</script>
- 數組語法:可以將多個樣式對象應用到同一個元素
<div v-bind:style="[styleObjectA, styleObjectB]"></div>
注意:
-
自動添加前綴。在綁定style時,使用需要添加瀏覽器引擎前綴的CSS屬性時,Vue.js會自動偵測並添加相應的前綴。
-
CSS屬性名可以用駝峯式或者短橫線分隔來命名。但是使用短橫線分隔時,要用引號括起來
<div :style="{color:'red',width:'100px','background-color':'#ccc'}"></div>
<!-- background-color 必須加上引號,或者寫成backgroundColor 駝峯命名法 -->
v-bind的指令修飾符:
.camel
:特性會將大寫字符轉換成小寫字母,camel解決這種問題,用-
鏈接符會變爲駝峯命名法
<svg :view-box.camel="viewBox"></svg>
<!-- 被渲染爲 -->
<svg viewBox="xxxx"></svg>
.prop
:直接使用dom中的屬性,給屬性賦值
<div v-bind:text-content.prop="title"></div>
<!-- 相當於 -->
document.getElementsByTagName("div")[0].textContent = title
11、v-on
v-on
:事件監聽,並觸發綁定的JavaScript代碼,可以用@
簡寫
<div id="app">
<button v-on:click="add(1,$event)">點擊</button>
<p>按鈕被點擊了 {{ counter }} 次</p>
</div>
<script>
new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
add: function (num,e) {
console.log(e)
this.counter += 5;
}
}
})
</script>
注意:填寫多個參數時,可以用$event獲取事件對象
v-on指令的修飾符:
.stop
阻止冒泡行爲。點擊按鈕只會輸出button
<div id="app">
<div @click="console('div')">
<button @click.stop="console('button')">點擊</button>
</div>
</div>
<script>
new Vue({
el: "#app",
methods: {
console(str){console.log(str)}
},
})
</script>
.prevent
阻止默認事件。會調用event.preventDefault()
,組織默認事件。例如:下面點擊提交按鈕後,頁面不會重載
<div id="app">
<form v-on:submit.prevent="onSubmit">
<input type="submit">
</form>
</div>
<script>
new Vue({
el: "#app",
methods: {
onSubmit(){console.log("提交操作...")}
},
})
</script>
.capture
開啓事件捕獲模式。即事件從上向下依次執行,例如:點擊按鈕後,先輸出div再輸出button
<div id="app">
<div @click.capture="console('div')">
<button @click="console('button')">點擊</button>
</div>
</div>
<script>
new Vue({
el: "#app",
methods: {
console(str){console.log(str)}
},
})
</script>
.self
只當事件是從偵聽器綁定的元素本身觸發時才觸發回調。就是點擊自己的時候才執行,不會因爲冒泡或其他捕獲時執行。
<div id="app">
<div @click.self="console('div')">
<button @click="console('button')">點擊</button>
</div>
</div>
<script>
new Vue({
el: "#app",
methods: {
console(str){console.log(str)}
},
})
</script>
-
.once
只執行一次,多次點擊無效,太簡單了,不舉例了。 -
.passive
不阻止默認事件 。並要注意不要把.passive
和.prevent
一起使用,因爲.prevent
將會被忽略,同時瀏覽器可能會向你展示一個警告。
<div v-on:scroll.passive="onScroll">...</div>
解釋:passive是滾動行爲的默認事件,只要滾動給就會立即執行,不會等到onScroll
完成。在觸發觸摸事件時,執行了一個空的函數,也會讓頁面卡頓。因爲瀏覽器不知道監聽器到底會不會阻止默認事件,所以瀏覽器要等到執行完整個函數後,才能決定是否要滾動頁面。passive事件監聽器,允許開發者告訴瀏覽器,監聽器不會阻止默認行爲,從而瀏覽器可以放心大膽的滾動頁面,這樣可以大幅度提升移動端頁面的性能,因爲據統計只有20%的觸摸事件會阻止默認事件。
我們還需要注意,修飾符的順序也非常重要。相應的代碼會以同樣的順序產生。例如:
v-on:click.prevent.self
:會阻止所有的點擊的默認事件,而v-on:click.self.prevent
:只會阻止對元素自身點擊的默認事件
v-on中的按鍵修飾符:
- 按鍵碼修飾符
下面的代碼,只有當我們按下回車鍵時纔會觸發submit函數執行
<input v-on:keyup.enter="submit">
常用的按鍵碼別名:.enter
(回車鍵)、.tab
(tab鍵)、.delete
(捕獲“刪除”和“退格”鍵)、.esc
、
.space
、.up
、.down
、.left
、.right
也可以在全局自定義按鍵修飾符的別名,使用Vue.config.keyCodes
對象
Vue.config.keyCodes = {
'f1-key':112 //但需要使用-鏈接
}
v-on中鼠標按鈕修飾符:
下面的代碼,只有當我們按下鼠標右鍵時纔會觸發change函數執行
<button v-on:click.right="change"></button>
鼠標按鈕修飾符只有三個.left
、.right
、.middle
12、v-for
v-for
:基於一個數據來渲染一個列表。
在數組中:v-for="(item, index) in items"
,其中item
是被迭代的數據的別名,index
是當前的索引(可選值),items
是數據源。
在對象中:v-for="(value, key, index) in items"
,其中value
是被迭代的數據的別名,key
是鍵值(可選值),index
是當前的索引(可選值),items
是數據源。
在使用v-for
時,還需要指定一個唯一的key
值,vue
會根據key
值找到對應的dom
,會進行比對,如果發生變化,可以準確的進行更新,便於重排和重繪
<div v-for="(item,index) in items" :key="item.id">
{{ item }}
</div>
注意:不能把key值給template,必須要給真實的元素
<template v-for="(item,index) in items">
<div :key="`${key}_1`">{{ item }}</div>
<span :key="`${key}_2`">{{ item }}</span>
</template>
注意:vue會爲了儘可能的節省性能,當vue的發現兩個dom相同時,就不會替換,會複用元素。如下,當切換時,input框不會替換,我們通常爲input添加key值解決。
<div v-if="flag">
<label for="name">name</label>
<input type="text">
</div>
<div v-else>
<label for="name">age</label>
<input type="text">
</div>
我們儘量不要將v-for
和v-if
放在同一個元素上使用,因爲v-for
的優先級比v-if
高,每一個dom元素都會進行相同的v-if
判斷,十分影響性能。
13、v-model
v-model
:表單元素的雙向數據綁定。數據更新元素會更新、元素更新數據也會更新。本質上v-model
是value和input事件的語法糖
<div id="app">
<input type="text" v-model="data"> {{ data }}
</div>
<script>
const vm = new Vue({
el:"#app",
data:{
data:""
}
})
</script>
其實底層就是通過控制value和input事件來實現的。如下:
<div id="app">
<input type="text" :value="data" @input="inputHandle"> {{ data }}
</div>
<script>
const vm = new Vue({
el:"#app",
data:{
data:""
},
methods:{
inputHandle(e){
this.data = e.target.value
}
}
})
</script>
v-model在不同的表單元素上使用
- 在
input
和textarea
是value
的值 - 在單選框中,爲選中的
value
值 - 在複選框中,是一個數組,每一項是選中的
value
- 在下拉框中,單選下拉框是選中的
option
中的值,多選是一個數組,每一項是選中的option
中的值
v-model中的修飾符:
.lazy
:使用change事件而非input事件,如果不需要實時更新,則可以用.lazy
.trim
:去掉前後的空格.number
:因爲v-model綁定數據是一個字符串,會將數據中的字符串轉爲number類型
14、v-slot
v-slot
:插槽