ue.js中的transition確實(shí)很棒。毫無(wú)疑問(wèn),它們可以非常輕松地讓?xiě)?yīng)用程序栩栩如生,但是通常必須在每個(gè)項(xiàng)目中從頭開(kāi)始編寫(xiě)它們,甚至還需要引入animate.css之類(lèi)的CSS庫(kù)來(lái)使它們功能更強(qiáng)大。
如果我們可以將它們封裝到組件中,并在多個(gè)項(xiàng)目中簡(jiǎn)單地重用它們,結(jié)果會(huì)怎樣呢?我們將介紹幾種定義transition的方法,并深入研究如何使它們真正可重用。
定義transition的最簡(jiǎn)單方法是使用transition·或transition-group組件。這需要為transition定義一個(gè)name`和一些CSS。
看起來(lái)容易,對(duì)吧?然而,這種方法有一個(gè)問(wèn)題。我們不能在另一個(gè)項(xiàng)目中真正重用這個(gè)transition。
如果我們將前面的邏輯封裝到一個(gè)組件中,并將其用作一個(gè)組件,結(jié)果會(huì)怎樣呢?
// FadeTransition.vue
<template>
<transition name="fade">
<slot></slot>
</transition>
</template>
<script>
export default {
};
</script>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>
// App.vue
<template>
<div id="app">
<button v-on:click="show=!show">
Toggle transition
</button>
<fade-transition>
<div v-if="show" class="box"></div>
</fade-transition>
</div>
</template>
<script>...</script>
<style>...</style>
通過(guò)在transition組件中提供一個(gè)slot,我們幾乎可以像使用基本transition組件一樣使用它。這比前面的例子稍微好一點(diǎn),但是如果我們想要傳遞其他特定于transition的prop,比如mode或者一些hook,該怎么辦呢
幸運(yùn)的是,Vue 中有一個(gè)功能,使我們可以將用戶(hù)指定的所有額外props和監(jiān)聽(tīng)器傳遞給我們的內(nèi)部標(biāo)簽/組件。如果你還不知道,則可以通過(guò)$attrs訪(fǎng)問(wèn)額外傳遞的 props,并將它們與v-bind結(jié)合使用以將它們綁定為props。這同樣適用于通過(guò)$listeners進(jìn)行的事件,并通過(guò)v-on對(duì)其進(jìn)行應(yīng)用。
「完整事例地址:https://codesandbox.io/s/yjl1wjyoy1?from-embed」
現(xiàn)在,我們可以傳遞普通transition組件可以接受的任何事件和支持,這使得我們的組件更加可重用。但為什么不更進(jìn)一步,增加通過(guò) prop 輕松定制持續(xù)時(shí)間的可能性。
Vue 為transition組件提供了一個(gè)duration prop,然而,它是為更復(fù)雜的動(dòng)畫(huà)鏈接而設(shè)計(jì)的,它幫助 Vue 正確地將它們鏈接在一起。
在我們的案例中,我們真正需要的是通過(guò)組件prop控制CSS animation/transition。我們可以通過(guò)不在CSS中指定顯式的CSS動(dòng)畫(huà)持續(xù)時(shí)間,而是將其作為樣式來(lái)實(shí)現(xiàn)。我們可以借助transition hook來(lái)做到這一點(diǎn),該transition hook與組件生命周期 hook 非常相似,但是它們?cè)谶^(guò)渡所需元素之前和之后被調(diào)用。讓我們看看效果如何。
「完整事例地址:https://codesandbox.io/s/j4qnjvmwz9?from-embed」
現(xiàn)在,我們可以控制實(shí)際的可見(jiàn)過(guò)渡時(shí)間,這使我們可重用的過(guò)渡變得靈活且易于使用。但是,如何過(guò)渡多個(gè)元素(如列表項(xiàng))呢?
你想到的最直接的方法可能是創(chuàng)建一個(gè)新組件,比如fade-transition-group,然后將當(dāng)前transition標(biāo)簽替換為transition-group標(biāo)簽,以實(shí)現(xiàn) group transition。如果我們可以在相同的組件中這樣做,并公開(kāi)一個(gè)將切換到transition-group實(shí)現(xiàn)的group prop,那會(huì)怎么樣呢?幸運(yùn)的是,我們可以通過(guò)render函數(shù)或component和is屬性來(lái)實(shí)現(xiàn)這一點(diǎn)。
// FadeTransition.vue
<template>
<component :is="type"
:tag="tag"
enter-active-class="fadeIn"
leave-active-class="fadeOut"
move-class="fade-move"
v-bind="$attrs"
v-on="hooks">
<slot></slot>
</component>
</template>
<script>
export default {
props: {
duration: {
type: Number,
default: 300
},
group: {
type: Boolean,
default: false
},
tag: {
type: String,
default: "div"
}
},
computed: {
type() {
return this.group ? "transition-group" : "transition";
},
hooks() {
return {
beforeEnter: this.setDuration,
afterEnter: this.cleanUpDuration,
beforeLeave: this.setDuration,
afterLeave: this.cleanUpDuration,
leave: this.setAbsolutePosition,
...this.$listeners
};
}
},
methods: {
setDuration(el) {
el.style.animationDuration=`${this.duration}ms`;
},
cleanUpDuration(el) {
el.style.animationDuration="";
},
setAbsolutePosition(el) {
if (this.group) {
el.style.position="absolute";
}
}
}
};
</script>
<style>
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fadeIn {
animation-name: fadeIn;
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.fadeOut {
animation-name: fadeOut;
}
.fade-move {
transition: transform 0.3s ease-out;
}
</style>
// App.vue
...
<div class="box-wrapper">
<fade-transition group :duration="300">
<div class="box"
v-for="(item, index) in list"
@click="remove(index)"
:key="item"
>
</div>
</fade-transition>
</div>
...
「完整事例地址:https://codesandbox.io/s/pk9r5j2257?from-embed」
[文檔中][6]介紹了一個(gè)帶有transition-group元素的警告。我們基本上必須在元素離開(kāi)時(shí)將每個(gè)項(xiàng)目的定位設(shè)置為absolute,以實(shí)現(xiàn)其他項(xiàng)目的平滑移動(dòng)動(dòng)畫(huà)。我們也必須添加一個(gè)move-class并手動(dòng)指定過(guò)渡持續(xù)時(shí)間,因?yàn)闆](méi)有用于移動(dòng)的 JS hook。我們將這些調(diào)整添加到我們的上一個(gè)示例中。
再做一些調(diào)整,通過(guò)在mixin中提取 JS 邏輯,我們可以將其應(yīng)用于輕松創(chuàng)建新的transition組件,只需將其放入下一個(gè)項(xiàng)目中即可。
在此之前描述的所有內(nèi)容基本上都是這個(gè)小型 [transition 集合][7]所包含的內(nèi)容。它有 10 個(gè)封裝的transition組件,每個(gè)約1kb(縮小)。我認(rèn)為它非常方便,可以輕松地在不同的項(xiàng)目中使用。你可以試一試:)
我們從一個(gè)基本的過(guò)渡示例開(kāi)始,并最終通過(guò)可調(diào)整的持續(xù)時(shí)間和transition-group支持來(lái)創(chuàng)建可重用的過(guò)渡組件。我們可以使用這些技巧根據(jù)并根據(jù)自身的需求創(chuàng)建自己的過(guò)渡組件。希望讀者從本文中學(xué)到了一些知識(shí),并且可以幫助你們建立功能更好的過(guò)渡組件。
作者:Matt 譯者:前端小智 來(lái)源:medium 原文:https://levelup.gitconnected.com/vuejs-a40cc3fb4428
css3過(guò)渡 轉(zhuǎn)換
css3過(guò)渡(transition)允許我們?cè)谙薅ǖ臅r(shí)間內(nèi)從一個(gè)屬性值轉(zhuǎn)變到另一個(gè)屬性值.
●transition-property:指定要轉(zhuǎn)換的屬性
●transition-duration:指定轉(zhuǎn)換發(fā)生的持續(xù)時(shí)間
●transition-timing-function:指定轉(zhuǎn)換的速度在其持續(xù)時(shí)間內(nèi)如何變化
●transition-delay:指定過(guò)渡效果的延遲(以秒為單位)
在下面的例子中,我們將transition屬性設(shè)置為持續(xù)時(shí)間為5s的轉(zhuǎn)換效果.并設(shè)置ease-in定時(shí)函數(shù),該函數(shù)有淡入的效果.
css代碼:
transition:transform 5s ease-in;
過(guò)渡效果可以應(yīng)用于各種css屬性,包括:背景顏色,寬度,高度,不透明度等等.
在下面的例子中,div元素的寬度和高度都是100px,并有一個(gè)紅色的背景.我么為width屬性指定一個(gè)過(guò)渡效果,持續(xù)時(shí)間為3s.
css代碼:
div.transition{ width:100px; height:100px;background:red;color:white;transition:width 3s; }
div.transition:hover{ width:250px;}
效果如下:
如果你將光標(biāo)懸停在div元素上,則會(huì)從左向右移動(dòng).
當(dāng)光標(biāo)被移出div元素時(shí),它將逐漸變回原來(lái)的樣式.
transition-timing-function屬性指定過(guò)渡效果的速度曲線(xiàn).
它可以有以下值:
ease:動(dòng)畫(huà)開(kāi)始緩慢,然后加速(默認(rèn)值)
ease-in:緩慢開(kāi)始,然后加速,突然停止.
ease-out:快速啟動(dòng),但減速停止.
ease-in-out:類(lèi)似于緩解,但更加微妙的加速和減速.
linear:勻速轉(zhuǎn)換
cubic-bezier()函數(shù),它允許你在cubic-bezier(立方體-貝塞爾)函數(shù)中定義你自己的值.取值范圍為0~1之間.
css代碼:
transition-timing-function:cubic-bezier(0,0,1,1);
二 css3 transform:rotate()
css3中transform(轉(zhuǎn)換)允許你翻轉(zhuǎn),旋轉(zhuǎn),縮放和傾斜元素.
transform(轉(zhuǎn)換)是一種讓元素更改形狀,大小和位置的效果
css3支持2d和3d轉(zhuǎn)換.
設(shè)置15deg的角度旋轉(zhuǎn)(順時(shí)針?lè)较蛐D(zhuǎn)),css代碼如下:
transform:totate(15deg);
正值,順時(shí)針旋轉(zhuǎn);負(fù)值,逆時(shí)針旋轉(zhuǎn).
三 css3 transform-origin,translate(),skew()
transition-origin(原點(diǎn))屬性允許你更改要轉(zhuǎn)換元素的位置.該屬性的默認(rèn)值是50% 50%,對(duì)應(yīng)于元素的中間.
在下面的例子中,我們將transform-origin屬性和transform-ratate一起使用.x軸(水平)的原點(diǎn)從左側(cè)設(shè)定為30%.
y軸(垂直)的原點(diǎn)從上方設(shè)定為80%.
css代碼:
div.empty-div{position:relative;height:100px;width:100px;margin:30px;padding:10px;border:2px solid black;}
div.green-div{ padding:50px; position:absolute;background-color:LightGreen;border:2px solid red;transform:rotate(15deg);transform-origin:30% 80%;}
效果如下:
0 0 與左上相同,100% 100%與右下相同.
transform-origin屬性必須與transform屬性一起使用.
translate()方法從當(dāng)前位置移動(dòng)一個(gè)元素(根據(jù)給定的x軸和y軸的參數(shù)).正值會(huì)將元素
向下推到其默認(rèn)位置的右側(cè).而負(fù)值則會(huì)將元素向上并拖至其默認(rèn)位置的左側(cè).
css代碼:
transform:translate(120px,60px);
skew()通過(guò)給元素設(shè)置x軸和y軸的傾斜角度值來(lái)實(shí)現(xiàn)傾斜.
以下例子,沿著x軸將<div>元素傾斜45度
css代碼:
transform:skew(45deg);
-webkit-transform:skew(45deg);
如果沒(méi)有指定第二個(gè)參數(shù),則它的默認(rèn)值為零.
四 css3 scale()函數(shù)和多重變換
scale()方法根據(jù)已設(shè)定的高度和寬度參數(shù)來(lái)增加或減少元素的大小.1代表原始大小,2代表原始尺寸的兩倍,以此類(lèi)推.
css代碼:
transform:scale(0.7 0.7);
如果只傳遞一個(gè)參數(shù),則默認(rèn)寬度與高度都使用該參數(shù).
一次可以使用多個(gè)轉(zhuǎn)換.比如同時(shí)旋轉(zhuǎn)和縮放元素的大小.對(duì)元素應(yīng)用多個(gè)變換,只需要用空格隔開(kāi)它們.
css代碼:
transform:rotate(35deg) translate(120px);
五 css3關(guān)鍵幀與動(dòng)畫(huà)
動(dòng)畫(huà)讓一個(gè)元素從一種風(fēng)格變?yōu)榱硪环N風(fēng)格.
你可以根據(jù)需要更改任意數(shù)量的css屬性.
關(guān)鍵幀將保存元素在特定時(shí)間的樣式
@keyframes規(guī)則
當(dāng)你在@keyframes規(guī)則中指定css樣式時(shí),動(dòng)畫(huà)將在某些時(shí)間從當(dāng)前樣式逐漸變?yōu)樾聵邮?
要使動(dòng)畫(huà)起作用,必須將動(dòng)畫(huà)綁定到元素.
以下例子,將更改元素的背景顏色三次:動(dòng)畫(huà)完成50%,完成70%,動(dòng)畫(huà)完成100%時(shí).
@keyframes animation-name{ 0% {background-color:red;} 50% {background-color:yellow;} 70% {background-color:green;}
100% {background-color:green;} }
animation-name是為動(dòng)畫(huà)指定的名字,你可以設(shè)置成任意的名字.
作為百分比的替代方法,你可以使用from和to關(guān)鍵字分別代替0%起始點(diǎn),100%結(jié)束點(diǎn).
要使動(dòng)畫(huà)起作用,必須將動(dòng)畫(huà)綁定到元素.
在下面的例子中,動(dòng)畫(huà)持續(xù)一秒鐘,并將紅色div的背景顏色更改為綠色和藍(lán)色
div.animation{ width:100px;height:100px;background-color:red;animation-name:能否;animation-duration:1s;}
@keyframes 能否{ 0% {background-color:red;} 50%{ background-color:green;} 100%{background-color:blue;} }
效果如下:
背景顏色將在1s內(nèi)自動(dòng)變化.
animation-name:指定動(dòng)畫(huà)的名字.
animation-duration:指定所選動(dòng)畫(huà)的持續(xù)時(shí)間.
如果為指定animation-duration屬性,則動(dòng)畫(huà)將不起作用.因?yàn)槟J(rèn)值是0.
在CSS中實(shí)現(xiàn)一個(gè)從上往下的過(guò)渡效果,你可以使用transition屬性,并結(jié)合transform屬性。以下是一個(gè)簡(jiǎn)單的例子,演示了如何實(shí)現(xiàn)一個(gè)元素在鼠標(biāo)懸停時(shí)從上向下移動(dòng)的過(guò)渡效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.box {
width: 100px;
height: 100px;
background-color: blue;
transition: transform 0.5s ease-in-out;
}
.box:hover {
transform: translateY(50px);
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
在這個(gè)例子中,.box類(lèi)定義了一個(gè)方框,并指定了一個(gè)過(guò)渡效果,使得當(dāng)transform屬性改變時(shí)(即鼠標(biāo)懸停時(shí)),它會(huì)在0.5秒內(nèi)完成平滑的從上往下移動(dòng)50像素的變化。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。