- 組件用于封裝頁(yè)面的部分功能举庶,將功能的結(jié)構(gòu)会钝,樣式,邏輯代碼封裝為整體
- 提高功能的復(fù)用性和可維護(hù)性笼踩,更好的專注于業(yè)務(wù)邏輯
- 組件使用時(shí)為自定義HTML標(biāo)簽形式,通過(guò)組件名作為自定義標(biāo)簽名
<div id="app">
<!-- 普通HTML標(biāo)簽 -->
<p>p標(biāo)簽內(nèi)容</p>
<!-- Vue.js組件 -->
<my-com></my-com>
</div>
組件注冊(cè)
全局注冊(cè)
- 全局注冊(cè)的組件在注冊(cè)之后可以用于任意實(shí)例或者組件中
Vue.component('組件名',{/*選項(xiàng)對(duì)象*/});
- 注意:全局注冊(cè)必須設(shè)置在根Vue實(shí)例創(chuàng)建之前
例子:
<body>
<div id="app">
<p>這是p標(biāo)簽</p>
<my-component></my-component>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('my-component',{
template : '<div>這是我們?nèi)肿?cè)的組件</div>'
});
// 根實(shí)例
new Vue({
el: '#app',
data: {
}
})
</script>
</body>
組件基礎(chǔ)
- 本質(zhì)上谷市,組件是可以復(fù)用的Vue實(shí)例蛔垢,可以與new Vue接收相同的選項(xiàng), 比如data迫悠,methods鹏漆,生命周期鉤子等等
- 僅有的例外是像el這樣根實(shí)例特有的選項(xiàng)
組件命名規(guī)則
- 組件具有兩種命名規(guī)則:
- kebab-case:'my-component'(烤串命名法,短橫線鏈接多個(gè)單詞的命名方式)
-
PascalCase:'MyComponent'(傳統(tǒng)命名法创泄,帕斯卡命名法艺玲,每部分內(nèi)容的首字母大寫)
示例
- 注意:無(wú)論采用什么類型的命名方式,在DOM中都只有kebab-case可以使用
template 選項(xiàng)
-
template 選項(xiàng)用于設(shè)置組建的結(jié)構(gòu)鞠抑,最終被引入根實(shí)例或者其他組件中
模板字符串 -
注意:組件必須只有一個(gè)根元素(一個(gè)根元素饭聚,比如最外層的div就一對(duì))
設(shè)置了兩個(gè)根元素就會(huì)報(bào)錯(cuò)
data 選項(xiàng)
- data 選項(xiàng)用于存儲(chǔ)組件的數(shù)據(jù),與根實(shí)例不同搁拙,組件的data 選項(xiàng)必須為函數(shù)秒梳,數(shù)據(jù)設(shè)置在返回值對(duì)象中
- 這種實(shí)現(xiàn)方式是為了確保每個(gè)組件實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝,不會(huì)相互影響箕速。
Vue devtools可以看到清晰的結(jié)構(gòu)
局部注冊(cè)
-
局部注冊(cè)的組件只能用在當(dāng)前實(shí)例或組件中
使用烤串命令法的時(shí)候需要加引號(hào) -
單獨(dú)配置組件的選項(xiàng)對(duì)象:
-
ES6的對(duì)象屬性簡(jiǎn)寫:
使用ES6簡(jiǎn)寫的方式的兼容性沒(méi)有上面的好
組件通信
- 父組件向子組件傳值
- 子組件向父組件傳值
- 非父子組件傳值
- 其他通信方式
父組件向子組件傳值
- 通過(guò)子組件的props選項(xiàng)接收父組件的傳值
注意:props不要和data存在同名的屬性酪碘,否則會(huì)覆蓋 -
父組件設(shè)置方式如下:
第一行是靜態(tài)屬性設(shè)置,第二行是動(dòng)態(tài)設(shè)置盐茎,第三行是動(dòng)態(tài)設(shè)置常用操作
<body>
<div id="app">
<!-- 靜態(tài)屬性設(shè)置 -->
<my-component-a
title="這是靜態(tài)的標(biāo)題"
content="這是靜態(tài)的內(nèi)容"
></my-component-a>
<!-- 動(dòng)態(tài)屬性綁定 -->
<my-component-a
v-bind:title="'這是靜態(tài)的標(biāo)題兴垦,這是演示'"
:content="'這是靜態(tài)內(nèi)容'"
></my-component-a>
<!-- 動(dòng)態(tài)屬性綁定:常用操作 -->
<my-component-a
:title="item.title"
:content="item.content"
></my-component-a>
</div>
<script src="lib/vue.js"></script>
<script>
// 創(chuàng)建子組件
Vue.component('my-component-a',{
props : ['title','content'],
template : `
<div>
<h3>{{ title }}</h3>
<p>{{ content }}</p>
</div>
`
});
new Vue({
el: '#app',
data: {
item: {
title: '這是示例標(biāo)題',
content: '這是示例內(nèi)容'
}
}
});
</script>
</body>
Props命名規(guī)則
-
建議prop命名使用camelCase,父組件綁定時(shí)使用kebab-case
<body>
<div id="app">
<my-component
:item-title="item.title"
:item-content="item.content"
></my-component>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('my-component', {
props: ['itemTitle', 'itemContent'],
template: `
<div>
<h3>{{ itemTitle }}</h3>
<p>{{ itemContent }}</p>
</div>
`
})
new Vue({
el: '#app',
data: {
item: {
title: '這是示例標(biāo)題',
content: '這是示例內(nèi)容'
}
}
})
</script>
</body>
props練習(xí)
- 通過(guò)v-for創(chuàng)建組件
<body>
<div id="app">
<!-- 通過(guò) v-for 遍歷數(shù)據(jù) items字柠,創(chuàng)建組件并生成內(nèi)容 -->
<demo-item
v-for="item in items"
:item-title="item.title"
:item-content="item.content"
:key="item.id"
:item="item"
></demo-item>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('demoItem', {
props: ['itemTitle', 'itemContent', 'item'],
template: `
<div>
<h3>{{ itemTitle }}</h3>
<p> {{ itemContent }} </p>
</div>
`
})
new Vue({
el: '#app',
data: {
// 準(zhǔn)備給子組件使用的數(shù)據(jù)
items: [
{
id : 1,
title: '示例標(biāo)題1',
content: '示例內(nèi)容1'
},
{
id : 2,
title: '示例標(biāo)題2',
content: '示例內(nèi)容2'
},
{
id : 3,
title: '示例標(biāo)題3',
content: '示例內(nèi)容3'
},
]
}
})
</script>
</body>
單向數(shù)據(jù)流
- 父子組件間的所有prop都是單向下行綁定的探越,不能反向影響父組件
-
如果子組件要處理prop數(shù)據(jù),應(yīng)當(dāng)存儲(chǔ)在data中再操作
- 如果prop為數(shù)組或者對(duì)象的時(shí)候窑业,子組件操作將會(huì)影響到父組件的狀態(tài)
<body>
<div id="app">
<my-component
:initial-title="title"
:obj="obj"
:arr = 'arr'
></my-component>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('my-component', {
props: ['initialTitle', 'obj','arr'],
template: `
<div>
{{ title }}
{{ obj }}
{{ arr }}
<button @click="fn">按鈕</button>
</div>
`,
data () {
return {
title: this.initialTitle
}
},
methods: {
fn () {
// title只是個(gè)字符串钦幔,不會(huì)反向影響到父組件的狀態(tài)
this.title = '這是新的標(biāo)題';
// this.initialTitle = '這是新的標(biāo)題'; // 不會(huì)影響父組件
// obj是對(duì)象,會(huì)反向影響到父組件
this.obj.name = 'jack';
this.obj.age = '20';
// arr是數(shù)組数冬,也會(huì)反向影響到父組件
this.arr[0] = 4;
}
}
});
new Vue({
el: '#app',
data: {
title: '這是示例標(biāo)題',
obj: {
name: 'william',
age: 18
},
arr : [1,2,3]
}
});
</script>
</body>
props類型
- Prop 可以設(shè)置類型檢查节槐,這時(shí)需要將 props 更改為一個(gè)帶有驗(yàn)證需求的對(duì)象搀庶,并指定對(duì)應(yīng)類型拐纱。
- prop還可以同時(shí)指定多個(gè)類型哥倔,通過(guò)數(shù)組方式保存就可以了
String或者Number都可以
設(shè)置這個(gè)內(nèi)容檢測(cè)僅僅是檢測(cè)秸架,如果忽略這個(gè)錯(cuò)誤也是可以渲染內(nèi)容上去的,所以設(shè)置之后要看控制臺(tái)檢查錯(cuò)誤
props驗(yàn)證
- 當(dāng) prop 需要設(shè)置多種規(guī)則時(shí)咆蒿,可以將 prop 的值設(shè)置為選項(xiàng)對(duì)象
-
之前的類型檢測(cè)功能通過(guò) type 選項(xiàng)設(shè)置
-
required 用于設(shè)置數(shù)據(jù)為必填項(xiàng)
-
default 用于給可選項(xiàng)指定默認(rèn)值东抹,當(dāng)父組件未傳遞數(shù)據(jù)時(shí)生效
-
當(dāng)默認(rèn)值是數(shù)組或者對(duì)象的時(shí)候蚂子,必須為工廠函數(shù)返回的形式,避免引用類型在多個(gè)組件中產(chǎn)生相互影響的情況
- validator 用于給傳入的 prop 設(shè)置校驗(yàn)函數(shù)缭黔,return 值為false 時(shí) Vue.js 會(huì)發(fā)出警告
驗(yàn)證函數(shù)中沒(méi)法使用實(shí)例的methods食茎,data等功能
非props屬性
-
當(dāng)父組件給子組件設(shè)置了屬性,此屬性在props不存在馏谨,這時(shí)就會(huì)自動(dòng)綁定到子組件的根元素上
image.png - 如果組件根元素已經(jīng)存在了對(duì)應(yīng)屬性别渔,則會(huì)替換組件內(nèi)部的值
-
class 與 style 是例外,當(dāng)內(nèi)外都設(shè)置時(shí)惧互,屬性會(huì)自動(dòng)合并
-
如果不希望繼承父組件設(shè)置的屬性哎媚,可以設(shè)置inheritAttrs:false,但只適用于普通屬性喊儡,class 與 style 不受影響
子組件向父組件傳值
子組件傳向父組件需要通過(guò)自定義事件來(lái)實(shí)現(xiàn)
-
舉個(gè)例子:商品為子組件拨与,購(gòu)物車為父組件,父組件需要統(tǒng)計(jì)商品個(gè)數(shù)艾猜,就需要在子組件個(gè)數(shù)變化時(shí)傳值給父組件
-
子組件數(shù)據(jù)變化時(shí)买喧,通過(guò)$emit()觸發(fā)自定義事件
- 事件的名稱建議使用kebab-case命名方式
-
父組件監(jiān)聽(tīng)子組件的自定義事件,設(shè)置好處理程序
自定義事件傳值
-
子組件觸發(fā)事件時(shí)可以向父組件傳值
第一個(gè)參數(shù)就是事件名箩朴,第二個(gè)參數(shù)就是傳遞的數(shù)據(jù)信息 -
父組件在監(jiān)聽(tīng)事件時(shí)需要接收子組件傳遞的數(shù)據(jù)
-
也可以寫成自定義事件岗喉,對(duì)應(yīng)處理的程序
組件與v-model
-
v-model用于組件時(shí),需要通過(guò)props與自定義事件實(shí)現(xiàn)
實(shí)踐案例:
<body>
<div id="app">
<p>輸入框內(nèi)容: {{ iptValue }}</p>
<com-input v-model = 'iptValue'></com-input>
</div>
<script src="lib/vue.js"></script>
<script>
var comInput = {
props : ['value'],
template : `
<input
type="text"
:value="value"
@input = "onInput"
>
`
,
methods : {
onInput(event){
this.$emit('input',event.target.value)
}
}
}
new Vue({
el: '#app',
data: {
iptValue : ''
},
components : {
comInput
}
})
</script>
</body>
非父子組件傳值
什么是非父子組件炸庞?兄弟組件或者完全無(wú)關(guān)的兩個(gè)組件
兄弟組件傳值
兄弟組件之間是可以通過(guò)父組件進(jìn)行數(shù)據(jù)中轉(zhuǎn)的
<body>
<div id="app">
<!-- 父組件接收子組件A的數(shù)據(jù) -->
<com-a
@value-change="value = $event"
></com-a>
<!-- 父組件將數(shù)據(jù)傳遞給子組件B -->
<com-b
:value="value"
></com-b>
</div>
<script src="lib/vue.js"></script>
<script>
// 子組件A:發(fā)送數(shù)據(jù)
Vue.component('ComA', {
template: `
<div>
組件A的內(nèi)容: {{ value }}
<button
@click="$emit('value-change', value)"
>發(fā)送</button>
</div>
`,
data () {
return {
value: '這是組件A中的數(shù)據(jù)'
}
}
});
// 子組件B:接收數(shù)據(jù)
Vue.component('ComB', {
props: ['value'],
template: `
<div>
組件B接收到: {{ value }}
</div>
`
});
// 根實(shí)例(父組件)
new Vue({
el: '#app',
data: {
// 用于數(shù)據(jù)中轉(zhuǎn)
value: ''
}
})
</script>
</body>
EventBus
- 當(dāng)組件嵌套關(guān)系復(fù)雜的時(shí)候钱床,根據(jù)組件關(guān)系傳值會(huì)比較繁瑣
- 如果組件為了數(shù)據(jù)中轉(zhuǎn),data中會(huì)存在許多與當(dāng)前組件功能無(wú)關(guān)的數(shù)據(jù)
- EventBus (事件總線)是一個(gè)獨(dú)立的事件中心埠居,用于管理不同組件間的傳值操作
- EventBus 通過(guò)一個(gè)新的 Vue 實(shí)例來(lái)管理組件傳值操作查牌,組件通過(guò)給實(shí)例注冊(cè)事件、調(diào)用事件來(lái)實(shí)現(xiàn)數(shù)據(jù)傳遞
// 將新的Vue實(shí)例bus存放在一個(gè)叫做EventBus.js的文件中
var bus = new Vue();
-
發(fā)送數(shù)據(jù)的組件觸發(fā)bus事件滥壕,接收的組件給bus注冊(cè)對(duì)應(yīng)的事件
-
給 bus 注冊(cè)對(duì)應(yīng)事件通過(guò) $on() 操作
最后創(chuàng)建根實(shí)例執(zhí)行代碼即可
<body>
<div id="app">
<h3>購(gòu)物車</h3>
<product-item></product-item>
<product-total></product-total>
</div>
<script src="lib/vue.js"></script>
<!-- 引入EventBus.js要在vue.js引入之后 -->
<script src="EventBus.js"></script>
<script>
// 商品組件
Vue.component('ProductItem', {
template: `
<div>
<span>商品名稱:蘋果纸颜,商品個(gè)數(shù):{{ count }}</span>
<button
@click="countIns"
>+1</button>
</div>
`,
data () {
return {
count: 0
}
},
methods: {
countIns () {
// 給bus觸發(fā)自定義事件,傳遞數(shù)據(jù)
bus.$emit('countChange', 1);
this.count++;
}
}
});
// 計(jì)數(shù)組件
Vue.component('ProductTotal', {
template: `
<p>總個(gè)數(shù)為: {{ totalCount }}</p>
`,
data () {
return {
totalCount: 0
}
},
created () {
// 給 bus 注冊(cè)事件绎橘,并接收數(shù)據(jù)
bus.$on('countChange', (productCount) => {
// 實(shí)例創(chuàng)建完畢胁孙,可以使用 data 等功能
// 使用箭頭函數(shù),直接使用this
this.totalCount += productCount;
});
}
})
// 根實(shí)例
new Vue({
el: '#app',
data: {
}
});
</script>
</body>
其他通信方式
$root
-
$root 用于訪問(wèn)當(dāng)前組件樹(shù)根實(shí)例称鳞,設(shè)置簡(jiǎn)單的Vue應(yīng)用時(shí)可以通過(guò)此方式 進(jìn)行組件傳值
注冊(cè)兩個(gè)局部組件comA和comB
根據(jù)內(nèi)部的子組件直接訪問(wèn)到了根實(shí)例的數(shù)據(jù)
進(jìn)一步證明是根實(shí)例的證據(jù):(組件B是子組件A的子組件)
<body>
<div id="app">
<com-a></com-a>
</div>
<script src="lib/vue.js"></script>
<script>
// 根實(shí)例的子組件A的子組件B
var ComB = {
template: `
<div>
組件B: {{ $root.count }}
<button @click="clickFn">按鈕</button>
</div>
`,
methods: {
clickFn () {
this.$root.count = 200;
}
}
};
// 子組件A
var ComA = {
template: `
<div>
組件A: {{ $root.count }}
<button @click="clickFn">按鈕</button>
<com-b></com-b>
</div>
`,
methods: {
clickFn () {
this.$root.count = 100;
}
},
components: {
ComB
}
};
// 根實(shí)例
new Vue({
el: '#app',
data: {
count: 0
},
components: {
ComA
}
});
</script>
</body>
- 除了
$root
, Vue.js 中還提供了$parent
與$children
用于 便捷訪問(wèn)父子組件
$refs
-
$refs
用于獲取設(shè)置了ref屬性的HTML標(biāo)簽或者子組件 - 給普通HTML標(biāo)簽設(shè)置ref屬性涮较,
$refs
可以獲取DOM對(duì)象
- 給子組件設(shè)置ref屬性,渲染后可以通過(guò)
$refs
獲取子組件實(shí)例
mouted確認(rèn)組件已經(jīng)掛載完畢冈止,生命周期函數(shù)
組件插槽
便捷的設(shè)置組件內(nèi)容
單個(gè)插槽
-
如果我們希望組件標(biāo)簽可以像 HTML 標(biāo)簽一樣設(shè)置內(nèi)容狂票,那么組件的使用靈活度會(huì)很高
-
但平常我們書寫的組件,組件首尾標(biāo)簽中書寫的內(nèi)容會(huì)被拋棄
-
這個(gè)時(shí)候我們需要通過(guò) <slot> 進(jìn)行插槽設(shè)置
slot標(biāo)簽就代表了內(nèi)容區(qū)域 -
需要注意模板內(nèi)容的渲染位置
在父組件視圖模板中不能使用子組件的數(shù)據(jù) -
我們可以在 <slot> 中為插槽設(shè)置默認(rèn)值熙暴,也稱為后備內(nèi)容
具名插槽
-
如果組件中有多個(gè)位置需要設(shè)置插槽闺属,據(jù)需要給 <slot> 設(shè)置name慌盯,稱為具名插槽
default可以省略掉
簡(jiǎn)寫模式:
<body>
<div id="app">
<com-a>
<template v-slot:header>
<h3>組件的頭部?jī)?nèi)容</h3>
</template>
<!-- <template v-slot:default>
<p>組件的主體內(nèi)容1</p>
<p>組件的主體內(nèi)容2</p>
</template> -->
<p>組件的主體內(nèi)容1</p>
<p>組件的主體內(nèi)容2</p>
<template #footer>
<p>組件底部?jī)?nèi)容</p>
</template>
</com-a>
</div>
<script src="lib/vue.js"></script>
<script>
// 子組件
Vue.component('ComA', {
template: `
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
`
});
new Vue({
el: '#app',
data: {
}
});
</script>
</body>
作用域插槽
用于讓插槽可以使用子組件的數(shù)據(jù)
-
組件將需要被插槽使用的數(shù)據(jù)通過(guò) v-bind 綁定給 <slot>,這種用于給插槽傳遞數(shù)據(jù)的屬性稱為插槽 prop
-
組件綁定數(shù)據(jù)后掂器,插槽中需要通過(guò) v-slot 接收數(shù)據(jù)
dataObj指的是所有插槽prop的對(duì)象 -
如果只存在默認(rèn)插槽亚皂,同時(shí)又需要接收數(shù)據(jù),可以進(jìn)行簡(jiǎn)寫
default也是可以省略掉的
還可以通過(guò) ES6 的解構(gòu)操作進(jìn)行數(shù)據(jù)接收
<!-- 只具有默認(rèn)插槽的作用域插槽書寫方式 -->
<!-- <com-b v-slot="dataObj"> -->
<com-b #default="dataObj">
{{ dataObj }}
</com-b>
<!-- 通過(guò) ES6 的解構(gòu)操作接收作用域插槽的數(shù)據(jù) -->
<com-b v-slot="{ value, num }">
{{ value }}
{{ num }}
</com-b>
內(nèi)置組件
動(dòng)態(tài)組件
動(dòng)態(tài)組件適用于多個(gè)組件頻繁切換的處理
-
<component> 用于將一個(gè)‘元組件’渲染為動(dòng)態(tài)組件国瓮,以 is 屬性值決定渲染哪個(gè)組件
類似于v-if - 可以用來(lái)實(shí)現(xiàn)多個(gè)組件的快速切換孕讳,比如說(shuō)選項(xiàng)卡效果
<body>
<div id="app">
<!-- 按鈕代表選項(xiàng)卡的標(biāo)題功能 -->
<button
v-for="title in titles"
:key="title"
@click="currentCom = title"
>
{{ title }}
</button>
<!-- component 設(shè)置動(dòng)態(tài)組件 -->
<component :is="currentCom"></component>
</div>
<script src="lib/vue.js"></script>
<script>
// 設(shè)置要切換的子組件選項(xiàng)對(duì)象
var ComA = {
template: `<p>這是組件A的內(nèi)容:<input type="text"></p>`
};
var ComB = {
template: `<p>這是組件B的內(nèi)容:<input type="text"></p>`
};
var ComC = {
template: `<p>這是組件C的內(nèi)容:<input type="text"></p>`
};
new Vue({
el: '#app',
data: {
// 所有組件名稱
titles: ['ComA', 'ComB', 'ComC'],
// 當(dāng)前組件名稱
currentCom: 'ComA'
},
components: {
ComA, ComB, ComC
}
});
</script>
</body>
is 屬性會(huì)在每次切換組件時(shí),Vue 都會(huì)創(chuàng)建一個(gè)新的組件實(shí)例意思就是銷毀了再創(chuàng)建巍膘,無(wú)法進(jìn)行保留
keep-alive組件
主要用于保留組件狀態(tài)或避免組件重新渲染
-
include 屬性用于指定哪些組件會(huì)被緩存厂财,具有多種設(shè)置方式
第一種方式,注意峡懈,每一個(gè)組件之間是不能有空格的
第二種
第三種璃饱,正則表達(dá)式 -
exclude 屬性用于指定哪些組件不會(huì)被緩存
-
max屬性用于設(shè)置最大的緩存數(shù)
值得一提的是,不是選擇與否肪康,而是參與緩存就算一次
過(guò)渡組件
用于在Vue插入荚恶,更新,或者移除DOM的時(shí)候磷支,提供多種不同方式的應(yīng)用過(guò)渡谒撼,動(dòng)畫效果
transition組件
- 用于給元素和組件添加進(jìn)入/離開(kāi)過(guò)渡
- 條件渲染(v-if)
- 條件展示(使用v-show)
- 動(dòng)態(tài)組件
- 組件根節(jié)點(diǎn)
- 組件提供了6個(gè)class,用于設(shè)置過(guò)渡的具體效果
- 進(jìn)入的類名:
- v-enter
- v-enter-to
- v-enter-active
- 離開(kāi)的類名
- v-leave
- v-leave-to
- v-leave-active
<style>
/* 用于設(shè)置出場(chǎng)的最終狀態(tài) */
.v-leave-to {
opacity: 0;
}
/* 用于設(shè)置過(guò)渡的執(zhí)行過(guò)程 */
.v-leave-active {
transition: opacity 1s;
}
/* 用于設(shè)置入場(chǎng)的初始狀態(tài) */
.v-enter {
opacity: 0;
}
/* 用于設(shè)置入場(chǎng)的最終狀態(tài) */
.v-enter-to {
opacity: 0.5;
}
/* 用于設(shè)置入場(chǎng)的過(guò)程 */
.v-enter-active {
transition: all 1s;
}
</style>
<body>
<div id="app">
<button @click="show = !show">切換</button>
<transition>
<p v-if="show">hello world</p>
</transition>
</div>
<script src="./lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
show: true
}
});
</script>
</body>
transition組件
-
給組件設(shè)置name屬性雾狈,可以給多個(gè)元素廓潜,組件設(shè)置不同的過(guò)渡效果,需要將v-更改為name-的形式
比如:
<transition name="demo"> 的對(duì)應(yīng)類名前綴為:- demo-enter
- demo-leave....等等
-
通過(guò) appear 屬性善榛,可以讓組件在初始渲染時(shí)實(shí)現(xiàn)過(guò)渡
自定義過(guò)渡類名
自定義類名比普通類名優(yōu)先級(jí)更高辩蛋,在使用第三方 CSS 動(dòng)畫庫(kù)時(shí)非常有用
- 用于設(shè)置自定義過(guò)渡類名的屬性如下
- enter-class
- enter-active-class
- enter-to-class
- leave-class
- leave-active-class
- leave-to-class
- 用于設(shè)置初始過(guò)渡類名的屬性如下
- appear-class
- appear-to-class
- appear-active-class
<style>
.v-enter, .v-leave-to {
opacity: 0;
}
.v-enter-active, .v-leave-active {
transition: all .5s;
}
/* 自定義過(guò)渡效果優(yōu)先級(jí)更高 */
.test {
transition: all 3s;
}
</style>
</head>
<body>
<div id="app">
<button @click="show = !show">切換</button>
<transition
enter-active-class="test"
leave-active-class="test"
>
<p v-if="show">這是 p 標(biāo)簽</p>
</transition>
</div>
<script src="./lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
show: true
}
});
</script>
</body>
Animate.css 是一個(gè)第三方 CSS 動(dòng)畫庫(kù),通過(guò)設(shè)置類名來(lái)給元素添加各種動(dòng)畫效果
使用注意
- animate_ 前綴與compat版本
- 基礎(chǔ)類名animated
使用animate.css的一個(gè)簡(jiǎn)單案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link
rel="stylesheet"
/>
<!-- 不需要添加 animate__ 的兼容版本移盆,但是官方建議使用完整版本 -->
<!-- "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.compat.css" -->
</head>
<body>
<div id="app">
<button @click="show = !show">按鈕</button>
<!-- 通過(guò)自定義過(guò)渡類名設(shè)置悼院,給組件添加第三方動(dòng)畫庫(kù)的類名效果 -->
<transition
enter-active-class="animate__bounceInDown"
leave-active-class="animate__bounceOutDown"
>
<!-- 必須給要使用動(dòng)畫的元素設(shè)置基礎(chǔ)類名 animate__animated -->
<p
v-if="show"
class="animate__animated"
>hello world</p>
</transition>
</div>
<script src="lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
show: true
}
});
</script>
</body>
</html>
transition-group組件
- <transition-group> 用于給列表統(tǒng)一設(shè)置過(guò)渡動(dòng)畫
- tag屬性用于設(shè)置容器元素,默認(rèn)為<span>
- 過(guò)渡會(huì)應(yīng)用于內(nèi)部元素咒循,而不是容器
- 子節(jié)點(diǎn)必須要有獨(dú)立的key据途,動(dòng)畫才能正常工作
- 當(dāng)列表元素變更導(dǎo)致元素位移,可以使用
.v-move
類名設(shè)置移動(dòng)時(shí)的效果
列表移除添加小案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
ul {
position: relative;
}
.v-enter, .v-leave-to {
opacity: 0;
transform: translateX(100px);
}
.v-enter-active, .v-leave-active {
transition: all .5s;
}
/* 讓元素在離場(chǎng)的過(guò)程中脫離標(biāo)準(zhǔn)流 */
.v-leave-active {
position: absolute;
}
.v-move {
transition: all .5s;
}
</style>
</head>
<body>
<div id="app">
<input type="text"
v-model="newTitle"
@keyup.enter="addItem"
>
<transition-group
tag="ul"
>
<li
v-for="item in items"
:key="item.id"
@click="removeItem(item)"
>
{{ item.title }}
</li>
</transition-group>
</div>
<script src="./lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
items: [
{ id: 1, title: '示例內(nèi)容1'},
{ id: 2, title: '示例內(nèi)容2'},
{ id: 3, title: '示例內(nèi)容3'},
{ id: 4, title: '示例內(nèi)容4'},
{ id: 5, title: '示例內(nèi)容5'},
],
newTitle: '',
latestId: 5
},
methods: {
addItem () {
this.items.push({
id: this.latestId + 1,
title: this.newTitle
});
this.latestId++;
this.newTitle = '';
},
removeItem (item) {
var i = this.items.indexOf(item);
this.items.splice(i, 1);
}
}
});
</script>
</body>
</html>