一筹麸、簡介
Vue (讀音 /vju?/耸携,類似于 view) 是一套用于構(gòu)建用戶界面的漸進式框架纵诞。與其它大型框架不同的是忙干,Vue 被設(shè)計為可以自底向上逐層應(yīng)用器予。Vue 的核心庫只關(guān)注視圖層,易于上手捐迫。
Vue 有個特點是響應(yīng)式乾翔,當(dāng)數(shù)據(jù)發(fā)生變化時,視圖會自動響應(yīng)弓乙,元素會匹配新的數(shù)據(jù)末融。
在 JS 中叮贩,需要text = "hello world"; document.getElementById("id").innerHTML = text;
才能改變元素的值谨湘;
而 Vue 中侮穿,只需要text = "hello world"
安拟,元素的值就會自動改變访诱。
參考了Vue教程和Vue API泽示。
二贪染、使用 Vue
- 使用html
需要先使用<script></script>
引入Vue壕翩,再在之后的<script></script>
中使用new Vue()
創(chuàng)建 Vue涂乌。
<body>
<!-- 最新版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 指定版本 -->
<!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script> -->
<div id="div">
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#div"
})
</script>
</body>
el: "#div"
表示將 Vue 掛載到id = "div"
的元素上艺栈。
- 使用 main.js
先使用npm install vue
下載 Vue,在 main.js 中使用new Vue()
初始化湾盒。
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: "#app",
render: h => h(App)
})
App.vue
是主頁面湿右,render: h => h(App)
表示用主頁面來渲染 Vue,el: "#app"
表示將該 Vue 掛載到id="app"
的元素上罚勾,該元素一般在 index.html 里毅人。
注:通常使用第二種方式創(chuàng)建 Vue吭狡,界面代碼寫在.vue
文件中,通過 Vue Router 跳轉(zhuǎn)界面丈莺。
- 使用.vue文件
<template>
<div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped="scoped">
</style>
.vue
文件叫做單文件組件划煮,<template></template>
中為 html 語句。要在 div 中寫界面代碼缔俄,不然會報錯弛秋,因為每個組件必須只有一個根元素。
<script></script>
中為 JS 語句俐载,export default { }
中為 Vue 語句蟹略。
<style></style>
中為 CSS 語句,通常添加scoped="scoped"
瞎疼,表示樣式只在當(dāng)前組件中生效科乎。
注:后面的介紹語法都是在單文件組件使用的,而不是官方教程那樣在 html 中使用贼急。
三茅茂、模板語法
1、修改文本
使用{{ }}
為一個元素添加動態(tài)的內(nèi)容太抓。里面是一個變量空闲,變量為data
選項中的key。
<template>
<div>
<div>{{ name }}</div>
</div>
</template>
<script>
export default {
data() {
return {
name: "zhangsan",
};
}
}
</script>
- 表達(dá)式
{{ }}
里面可以使用變量走敌,也可以使用表達(dá)式碴倾。實際上,變量也是表達(dá)式掉丽。
算術(shù)表達(dá)式跌榔,如{{ name + "lisi" }}
。
三元表達(dá)式捶障,如{{ isOk ? "zhangsan" : "lisi" }}
僧须,isOk
是一個值為布爾的變量。
函數(shù)表達(dá)式项炼,如{{ name.toUpperCase() }}
担平。 - v-text
可使用v-text
指令來代替{{ }}
插值的功能,如<div v-text="name"></div>
相當(dāng)于<div>{{ name }}</div>
锭部。 - v-once
因為 Vue 的響應(yīng)式暂论,當(dāng)變量name
的值發(fā)生改變時,div 的內(nèi)容會自動改變拌禾;
若不想自動改變取胎,可使用v-once
指令,如<div v-once>{{ name }}</div>
湃窍。
使用v-once
指令后元素/組件及其子元素/組件只會渲染一次扼菠。 - v-html
變量的值通常是字符串摄杂、數(shù)字等坝咐,若想使用 html 語句循榆,可使用v-html
指令。
<template>
<div>
<div v-html="age"></div>
</div>
</template>
<script>
export default {
data: function() {
return {
age: "<b>20</b>"
};
}
}
</script>
<style scoped="scoped">
b {
color: red;
}
</style>
修改了 DOM 中的element.innerHTML
墨坚。此時相當(dāng)于<div><b>20</b></div>
秧饮。
注:scoped的樣式不能應(yīng)用于v-html
指令中的元素。如上面的 b 元素字體不會變?yōu)榧t色泽篮。
- 響應(yīng)式數(shù)據(jù)
寫在data
選項中的數(shù)據(jù)就是響應(yīng)式數(shù)據(jù)盗尸,選項是一個對象或返回對象的函數(shù),可通過this.$data
獲取該對象帽撑。
因為使用的是單文件組件泼各,所以選項必須使用函數(shù)。
插值時必須使用響應(yīng)式數(shù)據(jù)亏拉,其它全局變量無效扣蜻。
使用this.$data.age
獲取數(shù)據(jù),因為 Vue 實例代理了data
選項中的所有變量及塘,所以可使用this.age
獲取數(shù)據(jù)莽使。
有前綴_
和$
的變量不會被 Vue 實例代理,所以只能使用this.$data._age
獲取數(shù)據(jù)笙僚。- 新增響應(yīng)式數(shù)據(jù)
若有一個響應(yīng)式數(shù)據(jù)info: { title: "hello" }
芳肌,當(dāng)使用this.info.content = "world"
給對象添加一個新鍵值對時,該鍵值對并不是響應(yīng)式的肋层,{{ info.content }}
是沒有效果的亿笤。
可使用this.$set()
方法為對象新增響應(yīng)式的鍵值對,如this.$set(this.info, "content", "world")
栋猖,此時{{ info.content }}
才有效果净薛。
$set()
方法有三個參數(shù):- 參數(shù)一為一個對象或數(shù)組,必須是響應(yīng)式的掂铐。
- 參數(shù)二為對象的鍵或數(shù)組的索引罕拂。
- 參數(shù)三為數(shù)據(jù)的值。
- 刪除響應(yīng)式數(shù)據(jù)
使用this.info.title = null
或this.info.title = undefined
刪除一個數(shù)據(jù)全陨。
也可使用this.$delete()
方法刪除數(shù)據(jù)爆班,能夠保證 Vue 知道某數(shù)據(jù)被刪除。
方法有兩個參數(shù)辱姨,與$set()
方法的前兩個參數(shù)相同柿菩。
- 新增響應(yīng)式數(shù)據(jù)
- 修改屬性
在 html 中,通常元素的屬性會賦值為字符串雨涛。使用v-bind
指令枢舶,可為屬性綁定一個表達(dá)式懦胞。
<template>
<div>
<div v-bind:title="detailAderss">{{ adress }}</div>
</div>
</template>
<script>
export default {
data() {
return {
adress: "cd",
detailAderss: "成都成華區(qū)"
};
}
}
</script>
鼠標(biāo)指著cd時
v-bind
指令可簡寫成:
,如<div :title="detailAderss">{{ adress }}</div>
凉泄。
- 指令
指令(Directives)是帶有v-
前綴的特殊屬性躏尉,如v-bind
。
指令的值通常是一個表達(dá)式后众,除了v-for
胀糜,如v-bind:title="detailAderss"
后面的detailAderss
。
指令也有參數(shù)蒂誉,在:
后面教藻,如v-bind:title="detailAderss"
后面的title
就是指令的參數(shù)。
查看全部指令右锨。
- 動態(tài)參數(shù)
使用[]
為指令綁定一個變量括堤,變量的值即為指令的參數(shù)。
<template>
<div>
<div v-bind:[attName]="detailAderss">{{ adress }}</div>
</div>
</template>
<script>
export default {
data() {
return {
adress: "cd",
detailAderss: "成都成華區(qū)",
attName: "title"
};
}
}
</script>
此時相當(dāng)于<div v-bind:title="detailAderss">{{ adress }}</div>
绍移。
指令參數(shù)的值通常是一個字符串悄窃,值為null
則可以被顯性地用于移除綁定。
- 修飾符
使用.
為指令添加一個修飾符登夫,修飾符用于指出指令應(yīng)該實現(xiàn)某個功能广匙,如v-on:click.prevent=""
。.prevent
修飾符的作用是讓事件對象調(diào)用event.preventDefault()
恼策。
可同時添加多個修飾符鸦致,如v-on:click.prevent.once=""
。
不同的指令有不同的修飾符涣楷,查看v-on修飾符分唾。
四、事件
-
綁定事件
在 html 中狮斗,使用<div onclick="clickAction()"></div>
來綁定 DOM 事件绽乔。
在 Vue 中,使用v-on
指令綁定 DOM 事件碳褒,如<div v-on:click="clickAction">
折砸。- 要注意的是,要刪除原事件前面的
on
沙峻,如onclick -> click
睦授。 - 當(dāng)表達(dá)式是一個函數(shù)調(diào)用時,在 html 中要使用
()
摔寨,如onclick="clickAction()"
去枷。 - 而在 Vue 中可以不用,但當(dāng)需要傳入?yún)?shù)時,則必須添加
()
删顶,如v-on:click="clickAction"竖螃、v-on:click="clickAction('a', 'b')"
。 - 函數(shù)傳入的參數(shù)可為
$event
逗余,即為事件對象特咆,如v-on:click="clickAction('a', $event)"
。
v-on
指令可簡寫成@
猎荠,如<div @click="clickAction">
坚弱。 - 要注意的是,要刪除原事件前面的
<template>
<div>
<div @click="clickAction">{{ funName }}</div>
</div>
</template>
<script>
export default {
data() {
return {
funName: "click me"
};
},
methods: {
clickAction: function(a) {
alert(event.type +" " + this.$data.funName)
}
}
}
</script>
方法要寫在methods
選項中,它是一個對象关摇,而每個方法則是對象中的一組鍵值對。
函數(shù)有兩個寫法碾阁,如clickAction: function() { }
输虱、clickAction() { }
。
若函數(shù)有參數(shù)脂凶,則寫成clickAction: function(a, b) { }
宪睹、clickAction(a, b) { }
。
- 箭頭函數(shù)
函數(shù)還有一種寫法是箭頭函數(shù)蚕钦,如clickAction: () => {}
亭病、clickAction: (a, b) => {}
。
若只有一個參數(shù)嘶居,可省略()
罪帖,如clickAction: a => {}
。
若函數(shù)里只有一句代碼邮屁,可省略{}
整袁,如clickAction: a => alert(a)
。
注:在普通函數(shù)中佑吝,this
指向 Vue 實例坐昙;但在箭頭函數(shù)中,this
不指向任何值芋忿。
- 可使用對象
在函數(shù)中炸客,event
對象表示函數(shù)的事件對象,this
對象則表示當(dāng)前的 Vue 實例戈钢。
當(dāng)未傳入?yún)?shù)時痹仙,函數(shù)默認(rèn)有一個傳入?yún)?shù),值為事件對象逆趣。
與 JS 一樣蝶溶,函數(shù)中也能使用arguments
對象,arguments[0]
表示傳入的第一個參數(shù),arguments[1]
表示傳入的第二個參數(shù)抖所,以至類推梨州。
- 鍵盤事件
使用@keydown、@keyup田轧、@keypress
綁定鍵盤事件暴匠,分別為按鍵按下、按鍵抬起傻粘、按鍵按下并抬起每窖。
在 JS 中,在函數(shù)中使用事件對象的key
或keyCode
屬性判斷按下了哪一個按鍵弦悉;在 Vue 中窒典,使用修飾符判斷按鍵,如<input @keyup.enter=""></input>
稽莉,表示在按下回車鍵時觸發(fā)瀑志。
- 普通按鍵
修飾符是事件對象的key
屬性的值通過kebab-case方式轉(zhuǎn)換而來的,如Enter->enter污秆、ArrowUp->arrow-up
劈猪。
修飾符也可以使用數(shù)字,即事件對象的keyCode
屬性的值良拼,如@keyup.enter=""
相當(dāng)于@keyup.13=""
战得。
Vue 內(nèi)置了一些修飾符:.enter .tab .delete (刪除或退格鍵) .esc .space .up .down .left .right
。
<template>
<div>
<input @keyup.enter="keyupAction"></input>
</div>
</template>
<script>
export default {
methods: {
keyupAction: function() {
alert(event.key + " " + event.keyCode)
}
}
}
</script>
有些舊瀏覽器的key
與keyCode
的對應(yīng)關(guān)系可能與新的不一致庸推,可以使用全局屬性Vue.config.keyCodes
修改常侦,如Vue.config.keyCodes.f1 = 112
。
- 粘滯鍵
在 JS 中予弧,通過事件對象的ctrlKey刮吧、altKey、shiftKey掖蛤、metaKey
屬性判斷是否按下了這幾種按鍵杀捻。
在 Vue 中,使用修飾符.ctrl .alt .shift .meta
判斷是否按下蚓庭,如@keyup.shift.enter=""
致讥,表示按下shift+enter時觸發(fā)。
注:在不同系統(tǒng)中器赞,alt垢袱、meta鍵可能不代表的按鍵不同,需要具體測試港柜。 - 精準(zhǔn)按鍵
使用修飾符.exact
判斷是否精確按下了按鈕请契,如@keyup.shift.enter.exact=""
只有在按下shift+enter時觸發(fā)咳榜,按下shitf+alt+enter時不會觸發(fā)。
鼠標(biāo)事件
在 JS 中爽锥,使用事件對象的button
屬性判斷哪個鼠標(biāo)按鍵被按下涌韩,012分別表示左鍵、中鍵氯夷、右鍵臣樱。
在 Vue 中,使用修飾符.left .right .middle
判斷哪個鼠標(biāo)按鍵被按下腮考,如@click.right=""
雇毫。綁定多個方法
v-on
指令的值可以是一個對象,可用于綁定多個方法踩蔚,如v-on="{ click: clickAction, dblclick: dblclickAction }"
棚放。
但這種方式不支持修飾符,也不支持給函數(shù)傳入?yún)?shù)寂纪。
五席吴、計算屬性
模板語法插值時,可向里面?zhèn)魅胍粋€表達(dá)式捞蛋,表達(dá)式可為一個變量,可為一個方法柬姚,也可為一個計算屬性拟杉。
<div>{{ name }}</div>
,name
是一個變量量承,值通常是一個簡單的值搬设,如{name: "zhangsan"}
。
<div>{{ getName() }}</div>
撕捍,getName()
是一個方法拿穴,可在函數(shù)里實現(xiàn)復(fù)雜的運算,最后返回一個值忧风。
methods: {
getName: function() {
//一系列運算
return "zhangsan"
}
}
<div>{{ getName1 }}</div>
默色,getName1
是一個計算屬性,也可在里面實現(xiàn)復(fù)雜的運算狮腿,最后返回一個值腿宰。
computed: {
getName1: function() {
//一系列運算
return "zhangsan"
}
}
計算屬性與方法
計算屬性與方法實際上都是函數(shù),但方法是寫在methods
選項中缘厢,而計算屬性寫在computed
選項中吃度,選項是一個對象。
在調(diào)用方法時贴硫,每調(diào)用一次都會執(zhí)行一次函數(shù)椿每。
在調(diào)用計算屬性時,只會執(zhí)行一次函數(shù),再次調(diào)用時則使用之前的返回值间护;若函數(shù)中使用的響應(yīng)式變量發(fā)生了變化亦渗,才會重新調(diào)用一次函數(shù)。如computed: { getName1: function() { return this.name.toUpperCase() } }
兑牡,只有當(dāng)name
的值變化時才會重新執(zhí)行函數(shù)衣撬。
注:響應(yīng)式變量指的是data
選項中的變量。何時使用計算屬性
計算屬性可以節(jié)約系統(tǒng)資源崇堰,當(dāng)使用了一個大數(shù)組時虚青,使用方法則會每次調(diào)用都遍歷一次數(shù)組,而使用計算屬性則只會遍歷一次苞也。計算屬性的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[1]
}
}
}
執(zhí)行fullName = "Sherlock Holmes"
時會調(diào)用set方法洛勉,使firstName和lastName變量更新;由于這兩變量發(fā)生了變化如迟,所以下次使用計算屬性fullName
時會重新執(zhí)行一次函數(shù)收毫。
六、偵聽
- 偵聽屬性
響應(yīng)式變量改變時計算屬性會重新調(diào)用一次函數(shù)殷勘,這實現(xiàn)了變量的被動監(jiān)聽此再,但這并不好用。
而使用偵聽屬性可以實現(xiàn)變量的主動監(jiān)聽玲销。
export default {
data() {
return {
watchProperty: ""
};
},
watch: {
watchProperty: function(val, oldval) {
alert("新值為" + val + "输拇,舊值為" + oldval)
}
}
}
偵聽屬性需要寫在watch
選項中,選項是一個對象贤斜。
對象鍵值對的值可以是一個函數(shù)策吠,函數(shù)會傳入兩個參數(shù),參數(shù)為變量的新值和舊值瘩绒。
還可以是字符串猴抹、數(shù)組、對象锁荔,詳見watch蟀给。
- 實例方法
除了寫在watch
選項中,還可以使用實例方法this.$watch()
堕战。
$watch()
一般寫在mounted
選項中坤溃,選項是一個函數(shù),它會在 Vue 實例被掛載后調(diào)用嘱丢。
<script>
export default {
data: function() {
return {
message: "message"
}
},
mounted: function() {
this.$watch("message", function(newVal, oldVal) {
alert(newVal+" "+oldVal)
}, {})
}
}
</script>
$watch()
有三個參數(shù):
- 參數(shù)一是一個表達(dá)式或函數(shù)薪介。
- 表達(dá)式通常是一個變量,會監(jiān)聽變量值是否發(fā)生了變化越驻。若要監(jiān)聽對象中的鍵值對汁政,可使用表達(dá)式
a.b.c
道偷。 - 為函數(shù)時,會監(jiān)聽函數(shù)的返回值是否發(fā)生了變化记劈。
- 表達(dá)式通常是一個變量,會監(jiān)聽變量值是否發(fā)生了變化越驻。若要監(jiān)聽對象中的鍵值對汁政,可使用表達(dá)式
- 參數(shù)二是一個回調(diào)函數(shù)勺鸦,會在監(jiān)聽的值發(fā)生變化時回調(diào)。函數(shù)有兩個參數(shù)目木,分別為新值與舊值换途。
- 參數(shù)三是一個對象,可使用兩個鍵
deep刽射、immediate
军拟,它們都是布爾值。- 若
deep
為true誓禁,當(dāng)監(jiān)聽一個對象時懈息,對象中任意鍵值對變化,就能觸發(fā)回調(diào)摹恰。為數(shù)組時不需這樣設(shè)置辫继。 - 若
immediate
為true,會立即觸發(fā)一次回調(diào)函數(shù)俗慈。
- 若
-
$watch()
有一個返回值姑宽,返回值是一個函數(shù),調(diào)用這個函數(shù)能取消監(jiān)聽闺阱。
如var unwatch = this.$watch("message", function() {});unwatch();
低千。
- 偵聽事件
通常,在組件上使用$emit()
觸發(fā)一個自定義事件馏颂,在父組件上使用v-on
指令監(jiān)聽這個事件。詳見 十一棋傍、組件 -- 3. 事件方法救拉。
那么,在本組件中怎么監(jiān)聽由$emit()
觸發(fā)的自定義事件呢瘫拣?可以使用實例方法this.$on()
實現(xiàn)亿絮。
<template>
<div>
<div @click="$emit('tap')">title</div>
</div>
</template>
<script>
export default {
mounted: function() {
this.$on("tap", function() {
alert(123)
})
}
}
</script>
$on()
一般寫在mounted
選項中,選項是一個函數(shù)麸拄,它會在 Vue 實例被掛載后調(diào)用派昧。
$on()
有兩個參數(shù):
- 參數(shù)一為一個字符串或數(shù)組。
- 字符串為
$emit()
觸發(fā)的事件名拢切。 - 數(shù)組為多個事件名組成的數(shù)組蒂萎。
- 字符串為
- 參數(shù)二為回調(diào)函數(shù),回調(diào)函數(shù)會接收所有
$emit()
觸發(fā)函數(shù)的參數(shù)淮椰。
$on(eventName, eventHandler)
偵聽一個事件
$once(eventName, eventHandler)
一次性偵聽一個事件五慈,事件名不支持?jǐn)?shù)組纳寂。
$off(eventName, eventHandler)
停止偵聽一個事件
七、class與style的綁定
在 html 中泻拦,通過<div class="class1 class2" style="width: 100px;height: 30px;"></div>
來綁定元素的 CSS 類名和樣式毙芜。
在 Vue 中,則使用v-bind
指令動態(tài)地綁定類名或樣式争拐。
- 對象語法
v-bind
指令可為屬性綁定一個變量腋粥,當(dāng)屬性為class
或style
時,這個變量可以是一個對象架曹。
- 變量寫法
- class
<div :class="classObject"></div>
隘冲,變量classObject為classObject: { class1: true, class2: true , class3: flase }
。此時相當(dāng)于<div class="class1 class2"></div>
音瓷。 - style
<div :style="styleObject"></div>
对嚼,變量styleObject為styleObject: { color: 'red', fontSize: '16px' }
。此時相當(dāng)于<div style="color: red;font-size: 16px;"></div>
绳慎。
在對象中纵竖,font-size
要寫成駝峰式fontSize
,也可以寫成'font-size'
杏愤。
- class
- 內(nèi)聯(lián)寫法
- class
<div :class="{ class1: enable1, class2: enable2, class3: enable3 }"></div>
靡砌,變量為enable1: true, enable2: true, enable3: false
。此時也相當(dāng)于<div class="class1 class2"></div>
珊楼。 - style
<div :style="{color: color, fontSize: size}"></div>
通殃,變量為color: 'red', size: '16px'
。此時也相當(dāng)于<div style="color: red;font-size: 16px;"></div>
厕宗。
font-size
要寫成駝峰式fontSize
画舌,也可以寫成'font-size'
。
- class
- 使用計算屬性
變量不僅可以是一個對象已慢,也可以是計算屬性曲聂。
<template>
<div>
<div v-bind:class="classObject"></div>
</div>
</template>
<script>
export default {
data() {
return {
pageIndex: 5
}
},
computed: {
classObject: function() {
return {
class1: this.pageIndex%3 == 0,
calss2: this.pageIndex%3 == 1,
calss3: this.pageIndex%3 == 2
}
}
}
}
</script>
變量為計算屬性時,可以通過一系列判斷后再返回對象佑惠。上面的作用是根據(jù)pageIndex
來使用不同的類名朋腋。
當(dāng)然,style也可以像上面一樣使用計算屬性膜楷。
- 數(shù)組語法
v-bind
指令可為屬性綁定一個變量旭咽,當(dāng)屬性為class
或style
時,這個變量可以是一個數(shù)組赌厅。
- 變量寫法
<div :class="classArray"></div>
穷绵,變量classArray為classArray: ['class1', 'class2']
。此時相當(dāng)于<div class="class1 class2"></div>
察蹲。
與對象語法一樣请垛,變量也可以是一個計算屬性催训,不同點在于返回值是一個數(shù)組。 - 內(nèi)聯(lián)寫法
- class
<div :class="['class1', 'class2']"></div>
宗收。
<div :class="[className, className2]"></div>
漫拭,變量為className1: "class1", className2: "class2"
。
<div :class="[isok1 ? 'class1' : '', {class2: isok2}]"></div>
混稽,變量為isok1: true, isok2: true
采驻。
上面三種都相當(dāng)于<div class="class1 class2"></div>
。 - style
<div :style="[colorstyle, fontstyle]"></div>
匈勋,變量為colorstyle: { color: 'red' }, fontstyle: { fontSize: '16px' }
礼旅,相當(dāng)于<div style="color: red;font-size: 16px;"></div>
。
font-size
要寫成駝峰式fontSize
洽洁,也可以寫成'font-size'
痘系。
- class
注:使用v-bind
指令時,Vue 會在 CSS 屬性前自動添加上各種瀏覽器的前綴饿自。
八汰翠、條件渲染
- v-if
與 JS 中的if、else if昭雌、else
一樣复唤,在 Vue 中也能通過指令v-if、v-else-if烛卧、v-else
來條件渲染不同的元素佛纫。
三個指令的值都是一個表達(dá)式,且表達(dá)式的結(jié)果應(yīng)該是一個布爾值总放。
必須按順序書寫呈宇,在一組元素中,帶有v-else-if
指令的元素可存在零個或多個局雄,帶有v-else
指令的元素可存在至多一個攒盈。
<template>
<div>
<div v-if="show1">if</div>
<div v-else-if="show2">else if</div>
<div v-else>else</div>
</div>
</template>
<script>
export default {
data() {
return {
show1: true,
show2: true
}
}
}
</script>
當(dāng)show1為true,渲染第一個div哎榴;當(dāng)show1為false,show2為true僵蛛,渲染第二個div尚蝌;當(dāng)都為false,渲染最后一個div充尉。
- template
當(dāng)需要條件渲染多個元素時飘言,可以使用 template。
如<div v-if="show1"><div>1</div><div>2</div></div>
驼侠,當(dāng) show1 改變時姿鸿,實際上是切換最外層帶有v-if
指令的這個 div谆吴,只不過是該div中有兩個子div。
若想同時切換多個元素苛预,可將最外層改成 template句狼,如<template v-if="show1"><div>1</div><div>2</div></template>
,此時實際上是在切換里面的兩個div热某。 - 元素的復(fù)用
<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>
Vue 會盡可能高效地渲染元素腻菇,通常會復(fù)用已有元素而不是從頭開始渲染。
上面例子的 label 元素和 input 元素在切換時昔馋,實際上是修改 label 元素的內(nèi)容和 input 元素的占位符筹吐。
若在輸入框中輸入了字符串,你會發(fā)現(xiàn)在切換時字符串并不會變化秘遏。
但這種情況有時并不符合要求丘薛。給需要重新渲染的元素設(shè)置不同的key
值,就能解決這個問題邦危。
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email">
</template>
此時 laebl 元素會復(fù)用洋侨,input 元素會重新渲染。
- v-show
使用v-show
指令也可以實現(xiàn)條件渲染铡俐,如<div v-show="show">show</div>
凰兑。
v-show
指令的值也是一個表達(dá)式,表達(dá)式的結(jié)果是一個布爾值审丘。
結(jié)果為true則顯示吏够,為false則不顯示,實際上是將元素的CSS切換成display: none
滩报。
v-if
在初始渲染時條件為假時什么也不做锅知;直到條件第一次變?yōu)檎鏁r,才會開始渲染脓钾。v-show
不管初始條件是什么售睹,元素都會被渲染。
v-if
有更高的切換開銷可训,而v-show
有更高的初始渲染開銷昌妹。因此,如果要頻繁地切換握截,則使用v-show
較好飞崖。
v-if
支持 template 元素,而v-show
則不支持谨胞。
九固歪、循環(huán)渲染
在 JS 中,使用for
來循環(huán)執(zhí)行代碼胯努;在 Vue 中牢裳,可以使用v-for
指令來循環(huán)渲染元素逢防。
通常,指令的值都是一個表達(dá)式蒲讯,而v-for
指令的值為alias in expression
忘朝。
其中expression的值可為數(shù)組、對象伶椿、數(shù)字辜伟、字符串、Iterable(詳見迭代協(xié)議)脊另。
- 在v-for中使用數(shù)組
v-for
指令的值為item in items
导狡,items
為data
選項中的變量,是一個數(shù)組偎痛;item
則是數(shù)組的元素旱捧,通常是一個對象。
<template>
<div>
<div v-for="item in items" :key="item.id">{{item.content}}</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{
id: "id1",
content: "item1"
},
{
id: "id2",
content: "item2"
}
]
}
}
}
</script>
v-for
指令的值還可以為"item,index in items"
踩麦,index
為元素的索引枚赡。
in
可以替換成of
,如item of items
谓谦、"item,index of items"
- 在v-for中使用對象
v-for
指令的值為value in object
贫橙,object
為data
選項中的變量,是一個對象反粥,value
為對象的鍵值對的值卢肃。
v-for
指令的值還可以為value,key in object
和value,key,index in object
,key
為對象的鍵值對的鍵才顿,index
為索引莫湘。
in
也可以替換成of
。
注:遍歷對象時郑气,會按Object.keys()
的結(jié)果遍歷幅垮。 - 在v-for中使用數(shù)字
v-for
指令的值為num in 10
,則會重復(fù)對應(yīng)次數(shù)尾组。 - 在v-for中使用字符串
v-for
指令的值為charStr in 'string'
忙芒,則會重復(fù)字符串長度的次數(shù),charStr
為每一個字符讳侨。
v-for
指令的值了也可為charStr,index in 'string'
匕争,index為索引值。 - 使用key
當(dāng)更新使用v-for
指令渲染的元素列表時爷耀,它默認(rèn)使用 就地更新 的策略。如果數(shù)據(jù)項的順序被改變拍皮,Vue 不會移動 DOM 元素來匹配數(shù)據(jù)項的順序歹叮,而是就地更新每個元素跑杭,并且確保它們在每個索引位置正確渲染。
為了重用和重新排序現(xiàn)有元素咆耿,可以給每項提供一個key
屬性德谅,如<div v-for="item in items" :key="item.id">{{item.content}}</div>
。
注:
key
的值應(yīng)該是一個字符串或數(shù)字萨螺,并且值不能夠重復(fù)窄做。
在組件上使用v-for
指令時,key
是必須的慰技。如<custom v-for="item in items" :key="item.id"></custom>
椭盏。 - 使用template
v-for
指令可以用在 template 元素上,如<template v-for="item in items" :key="item.id"><div>{{ item.id }}</div><div>{{ item.content }}</div></template>
吻商。
同v-if
指令一樣掏颊,當(dāng)需要循環(huán)渲染多個元素,可以使用 template艾帐。 - v-for與v-if
當(dāng)兩個指令同時使用時乌叶,如<div v-for="item in items" v-if="show" :key="item.id">{{item.content}}</div>
。
v-for
指令的優(yōu)先級比v-if
指令高柒爸,即先遍歷再判斷准浴。
注:Vue 不推薦這兩個指令組合使用。
十捎稚、表單綁定
在 html 中乐横,給一個輸入框設(shè)定初始值,如<input value="hello"></input>
阳藻。
當(dāng)在輸入框修改值后晰奖,實際上value
的值并沒有改變⌒饶啵可以監(jiān)聽oninput
事件匾南,在函數(shù)使用element.setAttribute()
來改變value
的值。
在 Vue 中蛔外,使用v-model
指令來實現(xiàn)雙向綁定蛆楞,實際上也是通過監(jiān)聽輸入事件以更新數(shù)據(jù)。
v-model
指令針對不同類型的 input 元素使用不同的值與事件夹厌。
text 和 textarea 使用 value 屬性和 input 事件豹爹;
checkbox 和 radio 使用 checked 屬性和 change 事件;
select 使用 value 屬性和 input 事件矛纹。
- 使用v-model
<input v-model="inputValue"></input>
inputValue
是data
選項中的一個變量臂聋,必須設(shè)置初始值,即使是一個""
。
checkbox 綁定的值是一個數(shù)組或布爾孩等,radio 綁定的值是一個布爾仁连,其他類型綁定的值則是一個字符串倘是。 - 修飾符
text 和 textarea 綁定的值默認(rèn)在input
事件中更新喊递,使用.lazy
修飾符砸狞,使其在change
事件中更新,如<input v-model.lazy="inputValue"></input>
权她。
text 和 textarea 綁定的值默認(rèn)是字符串虹茶,使用.number
修飾符,可以讓綁定的值變?yōu)閿?shù)字隅要,如<input v-model.number="age" type="number"></input>
蝴罪。
使用.trim
修飾符,可以自動去除字符串前后的空格拾徙,如<input v-model.trim="inputValue"></input>
洲炊。
十一、組件
組件是可復(fù)用的 Vue 實例尼啡,.vue
文件就是一個單文件組件暂衡。
- 使用組件
<template>
<div>
<CustomComponent></CustomComponent>
<Custom-Component></Custom-Component>
<custom-component></custom-component>
<CustomComponent1></CustomComponent1>
<custom-component1></custom-component1>
<custom-component2></custom-component2>
</div>
</template>
<script>
import CustomComponent from './CustomComponent.vue'
export default {
components: {
CustomComponent,
CustomComponent1: {
template: "<div>1234</div>",
data: function() {
return {}
}
}
'custom-component2': {
template: "<div>1234</div>",
}
}
}
</script>
可使用import
引入其他的.vue
文件,如組件CustomComponent崖瞭;也可以在當(dāng)前文件中直接創(chuàng)建組件狂巢,如組件CustomComponent1。
組件要寫在components
選項中书聚,選項是一個對象唧领。當(dāng)對象的鍵值對的鍵值相同時,可以省略值雌续,如{ CustomComponent }
相當(dāng)于{ CustomComponent: CustomComponent }
斩个。
使用組件時,可以使用大駝峰CustomComponent
驯杜,也可以使用分隔式Custom-Component
受啥,也可以使用小寫分隔式custom-component
,建議使用小寫分隔式鸽心,如<custom-component></custom-component>
滚局。
若注冊組件時就使用的小寫分隔式(此時兩端要加引號),如'custom-component2'
顽频,使用時也就只能使用小寫分隔式藤肢。
- 全局組件
上面的組件只能在當(dāng)前文件中使用,可使用Vue.component('name', {})
注冊全局組件糯景。要注意的是嘁圈,必須寫在new Vue({})
之前省骂。
- 組件屬性
每個元素都有屬性,自定義的組件在props
選項中聲明自定義屬性最住,可使用this.$props
獲取選項的值冀宴。
props
選項中聲明的屬性可以像data
選項中的變量一樣,直接在組件中使用温学。
<template>
<div>
<h1>{{ title }}</h1>
<p>{{ content }}</p>
</div>
</template>
<script>
export default {
data: function() {
return {
title: "component"
}
},
props: ['content']
}
</script>
組件的data
選項必須為一個函數(shù),它返回一個對象甚疟。這樣可以保證每個組件實例有只屬于自己的數(shù)據(jù)仗岖。
使用屬性
通過<custom-component content="message"></custom-component>
使用自定義的屬性,當(dāng)然也可以使用:content=""
為屬性綁定一個表達(dá)式览妖。
若<custom-component content></custom-component>
轧拄,表示content
的值為true。v-bind
當(dāng)組件中聲明的屬性很多時讽膏,如果都使用的話代碼就會很長檩电,如<custom-component name="" age="" adress="" phone=""></custom-component>
。
使用v-bind
指令可將所有屬性集中在一個對象中府树,如<custom-component v-bind="datas"></custom-component>
俐末,變量為datas: { name: "", age: "", adress: "", phone: "" }
。sync
上面不管是:content=""
還是v-bind=""
綁定變量時奄侠,都是單向的卓箫。當(dāng)組件內(nèi)的屬性值改變時,不會改變父組件變量的值垄潮。
若要進行雙向綁定烹卒,可使用.sync
修飾符,如:content.sync=""
弯洗、v-bind.sync=""
旅急。
注:.sync
修飾符只支持變量,不支持表達(dá)式牡整。屬性命名
自定義的屬性通常使用小駝峰命名藐吮,在使用時,可使用小駝峰或分隔式果正,如<custom-component contentValue=""></custom-component>
炎码、<custom-component content-value=""></custom-component>
。-
prop選項的類型
prop
選項可為數(shù)組或?qū)ο蟆?/p>- 為數(shù)組時秋泳,如
props: ['title', 'likes', 'isPublished']
潦闲。 - 為對象時,如
props: { title: String, likes: Number, isPublished: Boolean}
迫皱。- 對象鍵值對的值為數(shù)據(jù)類型歉闰,可使用
String辖众、Number、Boolean和敬、Array凹炸、Object、Date昼弟、Function啤它、Symbol
。 - 也支持構(gòu)造函數(shù)舱痘,如
function Person (firstName, lastName) { this.firstName = firstName;this.lastName = lastName }
变骡,通過props: { person: Person}
來使用。
- 對象鍵值對的值為數(shù)據(jù)類型歉闰,可使用
- 為數(shù)組時秋泳,如
-
props類型驗證
當(dāng)props
選項為對象時:- 可讓一個屬性支持一種數(shù)據(jù)類型芭逝,如
title: String
塌碌。 - 也可支持多種數(shù)據(jù)類型,如
title: [String, Number]
旬盯。 - 鍵值對的值也可以是一個對象台妆,如
title: { type: String }
,相當(dāng)于title: String
這個對象有多種鍵:-
type
表示屬性的數(shù)據(jù)類型胖翰,如title: { type: String }
接剩。 -
required
表示屬性是否必填,如title: { type: String, required: true }
泡态。 -
default
表示默認(rèn)值搂漠,如title: { type: String, default: "標(biāo)題" }
;
若數(shù)據(jù)類型為數(shù)組或?qū)ο竽诚遥仨毷褂煤瘮?shù)桐汤,如title: { type: Array, default: function() { return [] } }
。 -
validator
表示驗證函數(shù)靶壮,如title: {type: String, validator: function(value) { return value.length > 6 } }
怔毛,表示title的值的字符長度必須大于6。
-
注:
props
選項中的屬性會在組件實例創(chuàng)建之前進行驗證腾降,所以實例this
在default
或validator
的函數(shù)中是不可用的拣度。 - 可讓一個屬性支持一種數(shù)據(jù)類型芭逝,如
使用非props的屬性
<custom-component title=""></custom-component>
若組件中并沒有聲明title屬性,使用時螃壤,Vue 會將title自動添加到組件的根元素上抗果。若根元素上已經(jīng)設(shè)定了該屬性,會被覆蓋奸晴。但style冤馏、class
會發(fā)生合并。
若想讓未聲明的屬性不自動添加到組件的根元素上寄啼,需要設(shè)置inheritAttrs
選項為false逮光。
該選項并不會影響class代箭、style
的合并。
<script>
export default {
inheritAttrs:false
}
</script>
使用$attrs
屬性可獲取所有已使用且未在props
中聲明的屬性涕刚,它是一個對象嗡综,里面不包括class、style
杜漠。
<template>
<div>
<div val1="$attrs['val1']"></div>
<div val2="$attrs['val2']"></div>
<div v-bind="$attrs"></div>
<div>{{ $attrs["val1"] }}</div>
</div>
</template>
<script>
export default {
}
</script>
使用<custom-component val1="" val2=""></custom-component>
設(shè)置未聲明的屬性极景,在組件中也可使用$attrs
屬性來實現(xiàn)props
的功能,但不推薦驾茴。
- 事件方法
每個元素都有事件方法戴陡,自定義組件中使用實例方法$emit()
來聲明自定義方法。
<template>
<div>
<h1 @click="$emit('tap', 1, 2)">{{ title }}</h1>
<p>{{ content }}</p>
</div>
</template>
<script>
export default {
data: function() {
return {
title: "component"
}
},
props: ['content']
}
</script>
<h1 @click="$emit('tap', 1, 2)">{{ title }}</h1>
的功能是沟涨,當(dāng)點擊 h1 元素時,觸發(fā)一個名為 tap 的事件异吻,并為事件提供了兩個參數(shù)1和2裹赴;$emit
中事件名必須的。
當(dāng)然诀浪,也可以將$emit()
寫在@click="clickAction"
綁定的函數(shù)中棋返。
父組件通過<custom-component @tap="tapAction"></custom-component>
來監(jiān)聽 tap 事件,并通過tapAction: function(val1, val2) { }
使用這兩個參數(shù)雷猪,或在函數(shù)中通過arguments[0]睛竣、arguments[1]
使用這兩參數(shù)。
- native
在組件上監(jiān)聽原生事件時求摇,如<custom-component @click="clickAction"></custom-component>
射沟,會發(fā)現(xiàn)點擊時并不會調(diào)用 clickAction 函數(shù),因為只能監(jiān)聽$emit()
觸發(fā)的事件与境。
為了能順利調(diào)用函數(shù)验夯,需要使用.native
修飾符,如@click.native="clickAction"
摔刁。 - listeners
.native
修飾符可以監(jiān)聽根元素上的原生事件挥转,若根元素是一個div,監(jiān)聽的事件是input共屈,這當(dāng)然不會有作用绑谣。
可以使用$listeners
屬性獲取所有v-on
指令綁定的事件(不包括.native
修飾符的事件)。
這樣就能將父組件要監(jiān)聽的input
事件綁定到子組件的 input 元素上拗引,如<input v-on:input="$listeners.input"></input>
借宵。
也可以將所有事件都綁定到 input 元素上,如<input v-on="$listeners"></input>
寺擂。
- 組件使用v-model
使用v-model
指令時暇务,text 和 textarea 綁定的是 value 屬性 和 input 事件泼掠,相當(dāng)于<input :value="text" @input="text = $event.target.value">
。
組件也能使用v-model
指令垦细,也默認(rèn)綁定 value 屬性與 input 事件择镇,相當(dāng)于<custom-component :value="text" @input="text = $event">
。
在 input 元素中括改,$event
表示事件對象腻豌;而在組件中,$event
表示$emit()
的第二個參數(shù)嘱能。
- 更改默認(rèn)
組件使用v-model
指令時默認(rèn)綁定value
與input
事件吝梅,可使用model
選項更改默認(rèn)值。
選項是一個對象惹骂,對象有兩個鍵prop苏携、event
,分別為要綁定的屬性和事件对粪。
<script>
export default {
model: {
prop: "content",
event: "change"
},
props: ['content']
}
</script>
此時變更為綁定content屬性與change事件右冻。
- 插槽
html 元素大都可以通過<div>message</div>
在開始和結(jié)束標(biāo)簽中添加內(nèi)容。
而對于組件著拭,<custom-component>message</custom-component>
標(biāo)簽中的內(nèi)容是沒有任何效果的纱扭。
為了使添加的內(nèi)容生效,可以使用 slot 元素儡遮。
<template>
<div>
<h1 @click="$emit('tap', 1, 2)">{{ title }}</h1>
<slot></slot>
<p>{{ content }}</p>
</div>
</template>
此時乳蛾,<custom-component>message</custom-component>
標(biāo)簽中的message就會替換到<slot></slot>
的位置。
- 默認(rèn)值
在<slot></slot>
中添加默認(rèn)值鄙币,如<slot>hello</slot>
肃叶,那么當(dāng)<custom-component></custom-component>
時,就相當(dāng)于<custom-component>hello</custom-component>
十嘿。 - 具名插槽
有時候被环,我們可能需要添加多個插槽,它們在組件的不同位置详幽。
這時需要使用插槽的name
屬性筛欢。
<template>
<div>
<slot name="a"></slot>
<slot></slot>
<slot name="b"></slot>
</div>
</template>
<slot></slot>
是一個默認(rèn)插槽,name
默認(rèn)為default唇聘,相當(dāng)于<slot name="default"></slot>
版姑。
<custom-component2>
<div>default</div>
<template v-slot:a>aaa</template>
<template v-slot:b>bbb</template>
</custom-component2>
使用時具名插槽的內(nèi)容必須寫在 template 元素中,通過v-slot
指令的參數(shù)來匹配插槽的名字迟郎。
若為默認(rèn)插槽剥险,可省略<template v-slot:default></template>
。
內(nèi)容顯示的順序只與組件中各插槽的順序有關(guān)宪肖。
- 簡寫
同v-bind表制、v-on
指令可以簡寫成: @
一樣健爬,v-slot
指令可以簡寫成#
,如<template v-slot:default></template>
簡寫成<template #default></template>
么介。 - 作用域插槽
通常娜遵,給插槽添加內(nèi)容時,都是使用當(dāng)前文件中的數(shù)據(jù)壤短。如<custom-component2>{{ value }}</custom-component2>
设拟。
但組件內(nèi)部也提供了許多數(shù)據(jù)給外面的插槽使用,使用v-slot
指令來獲取組件提供的數(shù)據(jù)久脯。
<template>
<div>
<slot name="a"></slot>
<slot age="20" v-bind:adress="adressV"></slot>
<slot name="b"></slot>
</div>
</template>
<script>
export default {
data: function() {
return {
adressV: "cd"
}
}
}
</script>
在插槽 slot 上添加屬性 age 和 adress纳胧,也可使用v-bind
指令為屬性綁定一個表達(dá)式。
<custom-component2>
<template v-slot:default="value">
{{ value }}
</template>
</custom-component2>
v-slot:default="value"
表示給name="default"
的插槽(即默認(rèn)插槽)提供一個變量 value帘撰。
插槽就能夠使用變量 value 的數(shù)據(jù)跑慕,而 value 的值為{ "age": "20", "adress": "cd" }
,即在 slot 上添加的屬性與屬性值摧找。
若只有默認(rèn)插槽相赁,有另一種寫法,如<custom-component2 v-slot="value">{{ value }}</custom-component2>
- 使用部分?jǐn)?shù)據(jù)
上面 value 的值是一個對象{ "age": "20", "adress": "cd" }
慰于,若想只返回對應(yīng)屬性的值,可寫成v-slot:default="{age: a, adress: b}"
唤衫,這時a為20婆赠,b為cd。
因為當(dāng)對象中的鍵值相同時可以省略值佳励,所以可以寫成v-slot:default="{age, adress}"
休里,相當(dāng)于v-slot:default="{age: age, adress: adress}"
,這時age為20赃承,adress為cd妙黍。 - 動態(tài)插槽名
和其他指令一樣,可以使用[]
為指令設(shè)定動態(tài)的參數(shù)瞧剖,而v-slot
的參數(shù)即表示插槽名拭嫁。如v-slot:[name]="value"
,{ name: 'default' }
時相當(dāng)于v-slot:default="value"
抓于。
- 動態(tài)組件
使用 component 元素和is
屬性來使用動態(tài)組件做粤。
<component is="custom-component"></component>
相當(dāng)于<custom-componen></custom-componen>
,通常使用v-bind:is=""
綁定一個變量捉撮,就可以改變變量的值來切換不同的組件怕品。
除了使用組件,也可以用在普通的 html 元素上巾遭,如<component is="div"></component>
肉康。
-
贝彻溃活組件
動態(tài)組件通常用于多標(biāo)簽欄切換界面。你會發(fā)現(xiàn)吼和,切換不同界面時界面都會重置涨薪;這是因為在切換時,Vue 都會創(chuàng)建一個新的組件實例纹安。
但有時候尤辱,我們希望創(chuàng)建的組件能緩存下來,可以使用 keep-alive 元素厢岂,如<keep-alive><component :is="componentName"></component></keep-alive>
光督。
在不同組件同切換時,組件中的activated
和deactivated
這兩個生命周期鉤子函數(shù)會執(zhí)行塔粒,組件的子組件中的這兩個鉤子函數(shù)也會執(zhí)行结借。
keep-alive 元素有三個屬性:-
include
字符串或正則表達(dá)式,名稱匹配的組件會被緩存卒茬。
名稱為組件name
選項的值或父組件components
選項的鍵值對的鍵船老。 -
exclude
字符串或正則表達(dá)式。名稱匹配的組件不會被緩存圃酵。 -
max
數(shù)字柳畔。最多可以緩存多少組件實例,數(shù)字達(dá)到了郭赐,會釋放最久沒有訪問的實例薪韩。
注:keep-alive 元素只能用在有一個子組件的情形;若子組件使用了
v-for
捌锭,keep-alive 元素也沒有效果俘陷。 -
- 異步組件
通常,我們都是在本地創(chuàng)建組件观谦,然后在本地直接使用組件拉盾。
有時候,組件的代碼在服務(wù)器端豁状,則需要先從服務(wù)器獲取組件代碼捉偏,這時就要使用異步組件。
components: {
ServiceComponent: function(resolve, reject) {
var http = new XMLHttpRequest()
http.onreadystatechange = function() {
if (http.readyState == 4&&http.status == 200) {
const component = {
template: http.responseText
}
resolve(component)
} else {
reject("組件獲取失敗")
}
}
http.open("GET", "http_url", true)
http.send()
}
}
Vue 允許你以一個函數(shù)的方式定義你的組件泻红,這個函數(shù)會異步解析你的組件告私。
Vue 只有在這個組件需要被渲染的時候才會觸發(fā)該函數(shù),且會把結(jié)果緩存起來供以后再次渲染承桥。
函數(shù)有兩個回調(diào)參數(shù)驻粟,調(diào)用resolve()
表示組件加載成功,調(diào)用reject()
表示組件加載失敗,
訪問子組件
使用ref
屬性為元素或子組件注冊引用信息蜀撑,如<custom-component ref="custom"></custom-component>
挤巡。
再使用$refs
引用就會指向子組件的實例,如this.$ref.custom
酷麦。
若用在 html 元素上矿卑,引用就會指向 DOM 元素。
注:$refs
只會在組件渲染完成之后生效沃饶,并且它不是響應(yīng)式的母廷。應(yīng)該避免在 template 或計算屬性中訪問它。訪問父組件
使用$parent
可訪問父組件的實例糊肤,如this.$parent
琴昆。
- 依賴注入
子組件不應(yīng)該主動訪問父組件的實例,可以使用provide馆揉、inject
選項來依賴注入业舍,讓子組件能訪問父組件提供的數(shù)據(jù)或方法。
在父組件中使用provide
選項提供數(shù)據(jù)升酣,它是一個對象或返回對象的函數(shù)舷暮,如provide: {age: this.age};
在子組件中使用inject
選項接收數(shù)據(jù),它是一個對象或數(shù)組噩茄,如inject: ['age']
下面。
這樣就能在子組件中通過age來使用父組件中的this.age琳骡。
相比
$parent
來說豌注,依賴注入可以讓我們在任意后代組件中訪問數(shù)據(jù)颇蜡,而不需要暴露整個父組件實例祟蚀。
后代組件不需要知道被注入的數(shù)據(jù)來自哪里。
父組件不需要知道哪些后代組件使用了它提供的數(shù)據(jù)钉稍。
注入的數(shù)據(jù)是非響應(yīng)式的。
十二、過渡
使用 transition 元素蓄髓,給其他元素或組件添加進入、離開過渡/動畫效果舒帮。
將要過渡/動畫的元素放在 transition 中会喝,如<transition name=""><div></div></transition>
然后在CSS類名中添加過渡/動畫效果。
-
類名
在進入/離開的過渡中玩郊,會有6個類名切換肢执。
v-enter
定義進入過渡/動畫的開始狀態(tài)。在元素插入之前生效译红,在元素插入之后的下一幀移除预茄。為動畫時會在animationend
事件觸發(fā)時移除。
v-enter-active
定義進入過渡/動畫生效時的狀態(tài)。在這里設(shè)定進入過渡/動畫的過程時間耻陕、延遲和曲線函數(shù)拙徽。
v-enter-to
定義進入過渡/動畫的結(jié)束狀態(tài)。在元素插入之后下一幀生效 (v-enter
移除之時)诗宣,在過渡/動畫完成之后移除膘怕。
v-leave
定義離開過渡/動畫的開始狀態(tài)。在元素刪除之前生效召庞,在元素刪除之后的下一幀移除岛心。為動畫時會在animationend
事件觸發(fā)時移除。
v-leave-active
定義離開過渡/動畫生效時的狀態(tài)篮灼。被用來定義離開過渡/動畫的過程時間忘古、延遲和曲線函數(shù)。
v-leave-to
定義離開過渡/動畫的結(jié)束狀態(tài)穿稳。在元素刪除之后的下一幀生效 (v-leave
移除之時)存皂,在過渡/動畫完成之后移除。前面的v表示 transition 元素的
name
的值逢艘,如<transition name="div"></transition>
時使用div-enter-active
旦袋。
當(dāng)沒有設(shè)置name
時,默認(rèn)使用v它改。
v-enter-active
表示元素插入疤孕、執(zhí)行過渡/動畫、過渡/動畫結(jié)束這三個階段央拖。
v-enter-active = v-enter + v-enter-to
祭阀,大概相當(dāng)于v-enter
占v-enter-active
的前1%,v-enter-to
占后面99%鲜戒。
v-leave-active
與v-enter-active
類同专控。
<template>
<div>
<button @click="show = !show">switch</button>
<transition name="div">
<div v-if="show">animation</div>
</transition>
<transition name="div1">
<div v-if="show">transtion</div>
</transition>
</div>
</template>
<script>
export default {
data: function() {
return {
show: true
}
}
}
</script>
<style>
/* 過渡 */
.div1-enter-active, .div1-leave-active {
transition: all 1s ease;
}
/* 設(shè)置進入過渡執(zhí)行前或離開過渡執(zhí)行后的CSS,通常這兩個時間點CSS相同 */
.div1-enter, .div1-leave-to {
opacity: 0;
transform: translateX(60px);
}
/* 動畫 */
.div-enter-active {
animation: framename 2s;
}
/* 通常離開動畫是進入動畫的反向 */
.div-leave-active {
animation: framename 2s reverse;
}
/* from中設(shè)置動畫的初始狀態(tài)CSS to中設(shè)置結(jié)束狀態(tài)CSS */
@keyframes framename{
from{
transform: translate(0px, 0px);
}
25% {
transform: translate(50px, 0px)
}
50% {
transform: translate(50px, 50px)
}
75% {
transform: translate(0px, 50px)
}
to{
transform: translate(0px, 0px);
}
}
</style>
- 自定義類名
<transition name="div1" enter-active-class="aaa" leave-active-class="bbb">
<div v-if="show">transtion</div>
</transition>
.aaa, .bbb {
transition: all 1s ease;
}
使用屬性enter-class遏餐、enter-active-class伦腐、enter-to-class、leave-class失都、leave-active-class柏蘑、leave-to-class
自定義過渡/動畫的類名。
如上粹庞,aaa咳焚、bbb
相當(dāng)于div1-enter-active、div1-leave-active
類名庞溜。
監(jiān)聽類型
Vue 會監(jiān)聽transitionend
或animationend
事件來確定過渡/動畫的結(jié)束革半。若為一個元素同時設(shè)定過渡和動畫,Vue 并不知道監(jiān)聽哪一個事件來確定過渡/動畫的結(jié)束。
可以將type
屬性設(shè)為animation督惰、transition
來確定監(jiān)聽哪一個事件不傅,如<transition type="animation"></transition>
。持續(xù)時間
過渡/動畫的持續(xù)時間通常是在CSS屬性中設(shè)置赏胚,也可以使用duration
屬性設(shè)定持續(xù)時間访娶,如<transition duration="1000"></transition>
。
可以分別設(shè)定進入和離開的持續(xù)時間觉阅,如<transition duration="{ enter: 500, leave: 800 }"></transition>
崖疤。
duration
屬性設(shè)定的持續(xù)時間優(yōu)先度更高。當(dāng)?shù)搅嗽O(shè)定的持續(xù)時間典勇,即使過渡或動畫還在執(zhí)行劫哼,也會立即結(jié)束過渡或動畫。-
事件
transition 元素有before-enter割笙、enter权烧、after-enter、enter-cancelled伤溉、before-leave般码、leave、after-leave乱顾、leave-cancelled
這幾種事件板祝,會在過渡前、過渡時走净、過渡后券时、過渡取消時觸發(fā),如<transition @before-enter="beforeEnter" @enter="enter"></transition>
伏伯。
事件可以與 CSS 類名一起使用橘洞,建議單獨使用。使用<transition :css="false"></transition>
可屏蔽 CSS说搅。- 事件會給綁定的函數(shù)提供一個參數(shù)炸枣,參數(shù)值為執(zhí)行過渡/動畫的元素。
- 若為
enter蜓堕、leave
事件抛虏,還會多提供一個參數(shù)博其,參數(shù)為一個回調(diào)函數(shù)套才。
需要在過渡/動畫完成時執(zhí)行回調(diào)函數(shù),如enter: function(el, done) { done() }
慕淡。
若不執(zhí)行回調(diào)背伴,過渡/動畫就不會結(jié)束,就不會觸發(fā)after-enter
事件;執(zhí)行回調(diào)函數(shù)后傻寂,過渡/動畫會立即結(jié)束息尺。
初始渲染過渡
當(dāng)元素初次渲染到界面時,也可以執(zhí)行過渡疾掰。使用appear
屬性來實現(xiàn)初始渲染過渡搂誉。
<template>
<div>
<button @click="show = !show">switch</button>
<transition name="div" appear="appearname">
<div v-if="show">transtion init1</div>
</transition>
</div>
</template>
<script>
export default {
data: function() {
return {
show: true
}
}
}
</script>
<style scoped="scoped">
.div-enter-active, .div-leave-active {
transition: all 1s ease;
}
.div-enter, .div-leave-to {
opacity: 0;
transform: translateX(60px);
}
.div-appearname {
opacity: 0;
transform: translateX(60px);
}
.div-appearname-active {
transition: all 1s ease;
}
.div-appearname-to {
}
</style>
初始渲染過渡有三個類名,默認(rèn)為v-appear静檬、v-appear-active炭懊、v-appear-to
,表示初始渲染過渡前拂檩、初始渲染過渡中侮腹、初始渲染過渡完成。
根據(jù)name
屬性和appear
屬性的值決定類名稻励,若<transition name="div" appear="appearname">
父阻,那么類名為div-appearname、div-appearname-active望抽、div-appearname-to
加矛。
初始渲染過渡也可以通過appear-class、appear-active-class糠聪、appear-to-class
使用自定義類名荒椭,如<transition appear appear-active-class="" appear-class="" appear-to-class=""></transition>
。
初始渲染過渡也可以使用事件before-appear舰蟆、appear趣惠、after-appear、appear-cancelled
身害。表示初始渲染過渡前味悄、初始渲染過渡時、初始渲染過渡后塌鸯、初始渲染過渡取消侍瑟。
- 元素切換的過渡
上面介紹的都是單個元素的進入與離開過渡,若想使用多個元素間切換時的過渡丙猬,可使用v-if涨颜、v-else-if、v-else
茧球。
<template>
<div>
<button @click="show = !show">switch</button>
<transition name="div">
<div v-if="show" key="init1">transtion init1</div>
<div v-else key="init2">transtion init2</div>
</transition>
</div>
</template>
此時就會在兩個 div 中切換庭瑰。
必須給每個元素的
key
屬性設(shè)置不同的值,否則 Vue 會直接改變元素的內(nèi)容抢埋,就不會產(chǎn)生過渡效果弹灭。若兩個元素是不同的元素督暂,也可以不設(shè)置
key
屬性,但建議設(shè)置穷吮。
-
過渡模式
你會發(fā)現(xiàn)兩個元素它們會同時過渡逻翁,即離開與進入過渡同時進行〖裼悖可以使用mode
屬性修改過渡模式八回。-
in-out
新元素先進行過渡,完成之后當(dāng)前元素過渡驾诈。 -
out-in
當(dāng)前元素先進行過渡辽社,完成之后新元素過渡。(經(jīng)常使用)
當(dāng)不設(shè)置
mode
時翘鸭,兩者會同時過渡滴铅。
設(shè)置<transition name="div" appear="appearname" mode="out-in">
后
-
組件切換的過渡
通過動態(tài)組件實現(xiàn)組件切換的過渡,動態(tài)組件詳見 十一就乓、組件 -- 6. 動態(tài)組件汉匙。
這里因為是不同的組件,所以可以不設(shè)置key
屬性生蚁。
<template>
<div>
<button @click="name == 'component1' ? 'component2' : 'component1'">switch</button>
<transition name="div" mode="out-in">
<component :is="name"></component>
</transition>
</div>
</template>
<script>
export default {
data: function() {
return {
name: "component1"
}
},
components: {
component1: {
template: '<div>Component 1</div>'
},
component2: {
template: '<div>Component 2</div>'
}
}
}
</script>
<style scoped="scoped">
.div-enter-active, .div-leave-active {
transition: all 1s ease;
}
.div-enter, .div-leave-to {
opacity: 0;
transform: translateX(60px);
}
</style>
- 列表元素的過渡
上面我們過渡的噩翠,實際上都是單一元素或組件的過渡;若同時要過渡多個元素邦投,需要使用 transition-group 元素伤锚,且多個元素必須設(shè)置不同的key
。
不同于 transition 元素志衣,transition-group 會以一個真實元素呈現(xiàn)屯援,默認(rèn)為一個 span,使用tag
屬性更換為其他元素念脯。
<template>
<div>
<button @click="click">add</button>
<br>
<transition-group>
<div v-for="item in datas" :key="item" style="display: inline-block;">{{ item }}</div>
</transition-group>
</div>
</template>
<script>
export default {
data: function() {
return {
datas: [1, 2, 3, 4, 5],
next: 6
}
},
methods: {
click: function() {
var num = Math.floor(Math.random() * this.datas.length)
this.datas.splice(num, 0, this.next++)
}
}
}
</script>
<style scoped="scoped">
.v-enter-active, .v-leave-active {
transition: all 1s ease;
}
.v-enter, .v-leave-to {
opacity: 0;
transform: translateY(30px);
}
</style>
- 平滑過渡
可以看出狞洋,當(dāng)添加一個元素時,周圍的元素會瞬間移動到他們的新布局的位置绿店。
為了讓周圍元素能平滑的移動到新位置吉懊,可以使用v-move
類名。
像其他類名一樣假勿,可以使用name
屬性改變類名借嗽,也可以使用move-class
屬性自定義類名。
上面的例子添加.v-move { transition: all 1s ease; }
后
注:要使用平滑過渡转培,元素不能為display: inline
恶导。
- 狀態(tài)過渡
上面都是元素的進入或離開過渡,若想讓數(shù)據(jù)元素本身產(chǎn)生動效堡距,可以使用狀態(tài)過渡甲锡。如數(shù)字從0變到100的漸增式效果。
詳見狀態(tài)過渡羽戒。
十三缤沦、混入
混入 (mixin) 提供了一種非常靈活的方式,來分發(fā) Vue 組件中的可復(fù)用功能易稠,一個混入對象包含任意的組件選項缸废。
export default {
data: function() {
return {
b: 22,
c: 33
}
},
created: function() {
console.log('hello!11')
this.action()
},
methods: {
action: function() {
console.log('action11')
}
}
}
在.js
文件中添加要混入的選項。
<template>
<div>
<div>{{ a }}</div>
<div>{{ b }}</div>
<div>{{ c }}</div>
</div>
</template>
<script>
import Test from './Test11.js'
export default {
data: function() {
return {
a: 1,
b: 2//同名沖突時 使用組件中的數(shù)據(jù)
}
},
mixins: [Test],
//生命鉤子 同名沖突 兩個函數(shù)都會調(diào)用 優(yōu)先調(diào)用混入中的函數(shù)
created: function() {
console.log('hello!22')
this.action()
},
//方法 同名沖突 優(yōu)先使用組件中的方法
methods: {
action: function() {
console.log('action22')
}
}
}
</script>
在單文件組件中通過import
引入.js
文件驶社,混入的對象寫在mixins
選項中企量,選項是一個數(shù)組。
- 選項合并
當(dāng)組件和混入對象含有同名選項時亡电,這些選項會進行合并届巩。
-
data
選項里的數(shù)據(jù)對象會遞歸合并,若遇到同名沖突份乒,以組件的數(shù)據(jù)優(yōu)先恕汇。 - 值為對象的選項(
methods、components或辖、directives
等)瘾英,將被合并為同一個對象。若遇到同名沖突颂暇,以組件的數(shù)據(jù)優(yōu)先缺谴。 - 生命周期鉤子函數(shù)(
created、beforeCreate耳鸯、mounted
等)湿蛔,若遇到同名沖突,兩個函數(shù)會合并為一個數(shù)組县爬,它們都會調(diào)用煌集,但混入對象中的函數(shù)優(yōu)先調(diào)用。
全局混入
使用Vue.mixin({})
來注冊全局混入捌省,需要寫在new Vue()
前面苫纤。自定義合并
混入數(shù)據(jù)與組件數(shù)據(jù)合并時,有一個默認(rèn)的合并策略纲缓。使用Vue.config.optionMergeStrategies
可修改合并策略卷拘,詳見自定義選項合并策略。擴展
擴展(extend)和混入功能差不多祝高,都是給組件添加其他的選項功能栗弟。
混入使用mixins
選項,它是一個數(shù)組工闺;而擴展使用extend
選項乍赫,它是一個對象或函數(shù)瓣蛀。
<script>
export default {
extends: {
created: function() {
},
methods: {
click: function() {
}
}
}
}
</script>
擴展與混入的選項合并策略相同,不同點在于mixins可同時混入多組對象雷厂,而extend只能擴展一組對象惋增。
擴展的優(yōu)先級比混入高,但都低于組件本身改鲫。
- 全局?jǐn)U展
使用Vue.extend({})
來注冊全局?jǐn)U展诈皿,需要寫在new Vue()
前面。
十四像棘、自定義指令
Vue 有自帶的指令稽亏,但也可以使用directives
選項來自定義指令,選項是一個對象缕题。
<template>
<div>
<div v-redtext></div>
</div>
</template>
<script>
export default {
directives: {
redtext: {
inserted: function (el) {
el.style.color = "red"
el.innerText = "default text"
}
}
}
}
</script>
- 全局指令
使用Vue.directive('name', {})
注冊全局指令截歉,必須寫在new Vue()
前面。
- 鉤子函數(shù)
自定義指令有幾個鉤子函數(shù):-
bind
只調(diào)用一次烟零,指令第一次綁定到元素時調(diào)用怎披。在這里可以進行一次性的初始化設(shè)置。 -
inserted
元素插入父節(jié)點時調(diào)用 (僅保證父節(jié)點存在瓶摆,但不一定已插入到文檔中)凉逛。 -
update
元素的 VNode 更新時調(diào)用,可能發(fā)生在其子 VNode 更新之前群井。指令的值可能發(fā)生了改變状飞,也可能沒有。 -
componentUpdated
元素的 VNode 及其子 VNode 全部更新后調(diào)用书斜。 -
unbind
只調(diào)用一次诬辈,指令與元素解綁時調(diào)用。
-
- 鉤子函數(shù)參數(shù)
鉤子函數(shù)有4個參數(shù)荐吉,其中el
是可讀寫的焙糟,其他都是只讀的。-
el
指令綁定的元素样屠,可以用來直接操作 DOM穿撮。 -
binding
一個對象,包含以下的鍵痪欲。-
name
指令名悦穿,不包括v-
前綴。 -
value
指令的綁定值业踢,如v-directive="1 + 1"
中的2栗柒。 -
oldValue
指令綁定的前一個值,僅在update知举、componentUpdated
鉤子中可用瞬沦。無論值是否改變都可用太伊。 -
expression
指令的表達(dá)式。如v-directive="1 + 1"
中的1 + 1逛钻。 -
arg
指令的參數(shù)僚焦,可選。如v-directive:arg
中的arg绣的。 -
modifiers
一個包含修飾符的對象。如v-directive.mod1.mod2
欲账,修飾符對象為{ mod1: true, mod2: true }
屡江。
-
-
vnode
Vue 編譯生成的虛擬節(jié)點。詳見 VNode赛不。 -
oldVnode
上一個虛擬節(jié)點惩嘉,僅在update、componentUpdated
鉤子中可用踢故。
-
- 動態(tài)參數(shù)
指令可使用[]
設(shè)置動態(tài)參數(shù)文黎,如v-on:[dynamic]=""
。
自定義的指令也可以使用動態(tài)參數(shù)殿较,如v-redtext:[dynamic]
耸峭,在鉤子函數(shù)中通過binding.arg
獲取參數(shù)。
十五淋纲、渲染函數(shù)
通常使用模板來創(chuàng)建組件劳闹,也可以使用render
選項來創(chuàng)建組件。
<script>
export default {
render: function (createElement) {
return createElement('div', {}, [
createElement("h1", {}, "title")
])
}
}
</script>
<style>
</style>
上面例子相當(dāng)于<template><div><h1>title</h1></div></template>
洽瞬。
使用render
選項來創(chuàng)建組件時需要刪除最上面的<template></template>
本涕,也會忽略template
選項的值。
-
render
選項是一個函數(shù)伙窃,函數(shù)需要返回一個 VNode菩颖。函數(shù)有一個參數(shù),參數(shù)是一個回調(diào)函數(shù)为障,可通過這個回調(diào)函數(shù)來創(chuàng)建 VNode晦闰。 -
render
選項可以使用箭頭函數(shù),如render: createElement => createElement()
鳍怨。
回調(diào)函數(shù)通常使用字母h鹅髓,即render: h => h()
,可看到 main.js 中就是這種寫法京景。
- VNode
每個元素都是一個節(jié)點窿冯,每段文字也是一個節(jié)點,注釋和屬性也都是節(jié)點确徙。一個節(jié)點就是頁面的一個部分醒串,每個節(jié)點都可以有子節(jié)點 执桌。
Vue 通過建立一個虛擬 DOM 來追蹤自己要如何改變真實 DOM,虛擬 DOM 由虛擬節(jié)點(virtual node)組成芜赌,即VNode仰挣。
回調(diào)函數(shù)createElement()
可以創(chuàng)建一個虛擬節(jié)點 。它包含的信息會告訴 Vue 需要渲染什么樣的節(jié)點缠沈,包括節(jié)點及其子節(jié)點的描述信息膘壶。
VNode 必須是唯一的,下面是錯誤的洲愤。
render: function (createElement) {
var myParagraphVNode = createElement('p', 'hi')
return createElement('div', [
// 錯誤 - 重復(fù)的 VNode
myParagraphVNode, myParagraphVNode
])
}
但可以寫成:
render: function (createElement) {
return createElement('div', [
createElement('p', 'hi'), createElement('p', 'hi')
])
}
- 參數(shù)
createElement()
需要傳三個參數(shù)颓芭,如createElement("h1", {}, "title")
。- 參數(shù)一是必填項柬赐,可為一個 HTML 標(biāo)簽名亡问、組件選項對象,或者 resolve 了上述任何一種的
async
函數(shù)肛宋。 - 參數(shù)二是一個對象州藕,為元素的各種屬性,如
props酝陈、class床玻、id
等。 - 參數(shù)三是一個由子 VNode 組成的數(shù)組沉帮,如
createElement("div", {}, [createElement("h1", "title"), createElement("p", "content")])
笨枯。
或為一個字符串,內(nèi)容為元素的innerHTML
遇西。
- 參數(shù)一是必填項柬赐,可為一個 HTML 標(biāo)簽名亡问、組件選項對象,或者 resolve 了上述任何一種的
- 參數(shù)二
{
// 與 `v-bind:class` 的 API 相同馅精,
// 接受一個字符串、對象或字符串和對象組成的數(shù)組
'class': {
foo: true,
bar: false
},
// 與 `v-bind:style` 的 API 相同粱檀,
// 接受一個字符串洲敢、對象,或?qū)ο蠼M成的數(shù)組
style: {
color: 'red',
fontSize: '14px'
},
// 普通的 HTML attribute
attrs: {
id: 'foo'
},
// 組件 prop
props: {
myProp: 'bar'
},
// DOM property
domProps: {
innerHTML: 'baz'
},
// 事件監(jiān)聽器在 `on` 內(nèi)茄蚯,
// 但不再支持如 `v-on:keyup.enter` 這樣的修飾器具被。
// 需要在處理函數(shù)中手動檢查 keyCode碍沐。
on: {
click: this.clickHandler
},
// 僅用于組件壳咕,用于監(jiān)聽原生事件由缆,而不是組件內(nèi)部使用
// `vm.$emit` 觸發(fā)的事件。
nativeOn: {
click: this.nativeClickHandler
},
// 自定義指令皱碘。注意询一,你無法對 `binding` 中的 `oldValue`
// 賦值,因為 Vue 已經(jīng)自動為你進行了同步。
directives: [
{
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
bar: true
}
}
],
// 作用域插槽的格式為
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props => createElement('span', props.text)
},
// 如果組件是其它組件的子組件健蕊,需為插槽指定名稱
slot: 'name-of-slot',
// 其它特殊頂層 property
key: 'myKey',
ref: 'myRef',
// 如果你在渲染函數(shù)中給多個元素都應(yīng)用了相同的 ref 名菱阵,
// 那么 `$refs.myRef` 會變成一個數(shù)組。
refInFor: true
}
-
事件修飾符
在參數(shù)二的 on 中可設(shè)置事件監(jiān)聽缩功,但事件名后是不能添加修飾符的晴及,如on { click.once: this.clickAction }
是錯誤的。為了解決這個問題嫡锌,Vue 提供了一些前綴虑稼。-
&
表示.passive
修飾符。 -
!
表示.capture
修飾符势木。 -
~
表示.once
修飾符蛛倦。 -
~!
表示.capture.once、.once.capture
修飾符跟压。
如
on { !click: this.clickAction }
相當(dāng)于@click.capture="clickAction"
胰蝠。
而其他修飾符歼培,可以在函數(shù)中實現(xiàn)相同的功能震蒋。-
event.stopPropagation()
相當(dāng)于.stop
修飾符。 -
event.preventDefault()
相當(dāng)于.prevent
修飾符躲庄。 -
if (event.target !== event.currentTarget) return
相當(dāng)于.self
修飾符查剖。 -
if (event.keyCode !== 13) return
相當(dāng)于.enter、.13
修飾符噪窘。 -
if (!event.ctrlKey) return
相當(dāng)于.ctrl
修飾符笋庄。
-
- 插槽
- 使用
this.$slots
訪問插槽,每個插槽都是一個 VNode 組成的數(shù)組倔监。
如render: function (h) { return h('div', this.$slots.default) }
相當(dāng)于<div><slot></slot></div>
直砂。
如render: function (h) { return h('div', [this.$slots.header, this.$slots.default]) }
相當(dāng)于<div><slot name="header"></slot><slot></slot></div>
。
注:使用插槽時不能用箭頭函數(shù)浩习,因為不能訪問this静暂。 - 使用
this.$scopedSlots
訪問作用域插槽。
data: function() {
return {
title: "標(biāo)題",
content: "內(nèi)容"
}
},
render: function (h) {
return h('div', [this.$scopedSlots.header({
title: this.title
}), this.$scopedSlots.default({
content: this.content
})])
}
相當(dāng)于<div><slot :title="title" name="header"></slot><slot :content="content"></slot></div>
谱秽。
JSX
JSX是一個插件洽蛀,可使用模板來代替渲染函數(shù)。詳見JSX疟赊。
如render: h =>h("div", [h("h1", "title"), h("div", "contnet")])
可寫成redder: h=> (<div><h1>title</h1><div>content</div></div>)
郊供。函數(shù)式組件
組件比較簡單時,即沒有管理任何狀態(tài)近哟,沒有監(jiān)聽任何傳遞給它的狀態(tài)驮审,也沒有生命周期方法,它相當(dāng)于一個接受一些props
的函數(shù)。
在這樣的場景下头岔,我們可以將組件的functional
選項設(shè)為true塔拳,這意味它無狀態(tài),沒有響應(yīng)式數(shù)據(jù)(即沒有data
選項)峡竣,也沒有實例 (即沒有this
)靠抑。
functional: true,
props: {
},
render: function(createElement, context) {
createElement("div", context.data, context.children)
}
因為函數(shù)式組件只是函數(shù),所以渲染開銷也低很多适掰。
- context
因為在函數(shù)式組件中this
不可用颂碧,所以所有屬性都保存在參數(shù)context
中。
它是一個對象类浪,包含下列字段:-
props
提供所有自定義屬性的對象载城。 -
children
子虛擬節(jié)點的數(shù)組,通常作為createElement()
的第三個參數(shù)傳入組件费就。 -
slots
一個函數(shù)诉瓦,返回了包含所有插槽的對象。 -
scopedSlots
一個包含的作用域插槽的對象力细。 -
data
傳遞給組件的數(shù)據(jù)對象睬澡,通常作為createElement()
的第二個參數(shù)傳入組件。 -
parent
對父組件的引用眠蚂。 -
listeners
一個包含了所有父組件為當(dāng)前組件注冊的事件監(jiān)聽器的對象煞聪。data.on
的別名。 -
injections
如果使用了inject
選項逝慧,則該對象包含了被注入的屬性昔脯。注入詳見 十一、組件 -- 9. 訪問父組件 笛臣。
-
十六云稚、過濾器
過濾器用于一些常見的文本格式化。過濾器可以用在兩個地方:{{ }}
插值和 v-bind
指令的值沈堡,如<div>{{ mesage | filter }}</div>静陈、<div :title="message | filter"></div>
。
過濾器寫在filters
選項中踱蛀,選項是一個對象窿给。
<template>
<div>
<div>{{ message | lowercase | uppercase }}</div>
</div>
</template>
<script>
export default {
data: function () {
return {
message: "Hello World"
}
},
filters: {
lowercase: function(value) {
return value.toLowerCase()
},
uppercase: function(value) {
return value.toUpperCase()
}
}
}
</script>
過濾器使用|
與表達(dá)式相連,過濾器對象的鍵值對的值是一個函數(shù)率拒,且表達(dá)式為函數(shù)的第一個參數(shù)崩泡。
可多個過濾器串聯(lián)使用,如{{ message | lowercase | uppercase }}
猬膨,前面過濾器得出的結(jié)果變?yōu)楹竺孢^濾器的第一個參數(shù)角撞。
過濾器可傳入其他參數(shù)呛伴,如{{ message | lowercase(arg1, arg2) }}
,第一個參數(shù)為message谒所,參數(shù)二三為arg1热康、arg2。
- 全局過濾器
使用Vue.filter('name', function (value) {})
注冊全局過濾器劣领,必須寫在new Vue()
前面姐军。
當(dāng)全局過濾器與局部過濾器重名時,優(yōu)先使用局部過濾器尖淘。
十七奕锌、生命周期
整個 Vue 實例初始化到銷毀會經(jīng)歷如下過程。
生命周期分為多個階段村生,每個階段都會觸發(fā)相應(yīng)的鉤子惊暴。
鉤子有beforeCreate、created趁桃、beforeMount辽话、mounted、beforeUpdate卫病、updated油啤、beforeDestroy、destroyed
這幾種忽肛,詳見生命周期鉤子村砂。
它們都是函數(shù)烂斋,使用時不要用箭頭函數(shù)屹逛,因為箭頭函數(shù)中this
不指向 Vue 實例。