完整原文地址見簡書https://www.jianshu.com/p/f3b52299aaa6
本文內容提要
Vue常規動畫寫法
Vue過渡動畫 常規寫法與 例程
上例的另一種實現方式
入場動畫
出場動畫
出入場動畫同時實現時,可以簡化以上代碼
出場入場幀動畫
使用
name=
對動畫進行 片段式地 命名對動畫類的完全命名
完全命名的方式 使得 容易接入 第三方庫
注意以上案例,將
v-if
換成v-show
也是可以正常運行的顏色過渡和位移 動畫 結合
控制組合動畫時長 以某一類型動畫的時間爲準
控制組合動畫時長 以自定義的時長爲準
分別 統一 出入場動畫的時延
禁用CSS動畫,使用JS動畫
最基本的 多個 單元素標籤 切換案例
帶上入場 退場 動畫的 兩個單元素標籤切換
帶上入場 退場 動畫的 兩個組件 的切換
<component>
組件佔位 + is屬性 + 雙向綁定特性 實現上例效果列表動畫
狀態動畫
Vue常規動畫寫法
關鍵幀 --- CSS類 --- data數據 --- DOM的Class屬性
-- 使用@keyframes [關鍵幀實例名]
配置好關鍵幀;
-- 使用animation
配置關鍵幀
以及動畫過程到完成
的時延
,
完成動畫的定義【寫在一個CSS類中(如下的myAnimation
)】;
-- 在data
中定義一個以 上面定義的動畫CSS類
實例(如myAnimation
) 爲屬性值的 數據字段
(如myAnimateData
);
-- 在dom中使用:class=[以 動畫CSS類實例 爲屬性的 數據字段]
,
引用這個數據字段
(myAnimateData
)即可,至此完成動畫定義;
-- 數據字段
(如myAnimateData
)中,可以通過對 屬性值即動畫CSS類
實例的 布爾值的 改變,
去控制動畫的開關,如下 配置false 爲關:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
@keyframes leftToRight {
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
0% {
transform: translateX(0px);
}
}
.myAnimation {
animation: leftToRight 3s;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
myAnimateData: {
myAnimation: false
}
}
},
template: `
<div>
<div :class="myAnimateData">heheheda</div>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
運行效果,沒有動畫,DOM中也沒顯示對應的class:
改爲true:
<script>
const app = Vue.createApp({
data() {
return {
myAnimateData: {
myAnimation: true
}
}
},
template: `
<div>
<div :class="myAnimateData">heheheda</div>
</div>`
});
const vm = app.mount('#heheApp');
</script>
運行時產生動畫:
可以配合按鈕和點擊事件,動態 交互地 開關動畫:
<script>
const app = Vue.createApp({
data() {
return {
myAnimateData: {
myAnimation: true
}
}
},
methods: {
handleClick() {
this.myAnimateData.myAnimation = !this.myAnimateData.myAnimation;
}
},
template: `
<div>
<div :class="myAnimateData">heheheda</div>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
Vue過渡動畫 常規寫法與 例程
-- 使用transition: [時延] background-color ease;
定義 在一個時延內的過渡動畫
,
background-color
指定過渡對象是背景顏色
,ease
指定爲平緩地進行
;
-- 類似上例,在組件的data中,定義一個 對應CSS類的 Object類型數據字段
,並在其中包含過渡動畫
和定義好的背景顏色
的數據字段;
-- 在template
中,使用:class=[類實例名]
引用data
中的CSS類實例
即可;
-- 可以準備一個觸發事件
,在事件中反轉
兩個背景顏色值,由此可實現過渡動畫:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
.myTransition {
transition: 3s background-color ease;
}
.aquamarine {
background-color: aquamarine;
}
.orange {
background-color: orange;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
myTransitData: {
myTransition: true,
aquamarine: true,
orange: false
}
}
},
methods: {
handleClick() {
this.myTransitData.aquamarine = !this.myTransitData.aquamarine;
this.myTransitData.orange = !this.myTransitData.orange;
}
},
template: `
<div>
<div :class="myTransitData">heheheda</div>
<button @click="handleClick">使用transition切換背景色</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
運行效果:
點擊按鈕 觸發事件後 過渡的中途:過渡完畢:上例的另一種實現方式
-- 定義css動畫類
,
在dom節點直接使用class=[CSS動畫類]
配置上這個CSS動畫類;
-- data
中定義初始背景顏色鍵值
,打包成object
類型,
配置到DOM節點的:style=
上,作雙向綁定
;
-- 把css
中定義的背景顏色字段
都去掉,
直接寫在觸發事件
的方法中,在其中通過更改綁定的style字段的值
改變背景顏色;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
.myTransition {
transition: 3s background-color ease;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
styleObj: {
background: "aquamarine"
}
}
},
methods: {
handleClick() {
if (this.styleObj.background === 'aquamarine') {
this.styleObj.background = 'orange';
} else {
this.styleObj.background = 'aquamarine';
}
}
},
template: `
<div>
<div class="myTransition" :style="styleObj" >heheheda</div>
<button @click="handleClick">使用transition切換背景色</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
運行效果如上例;
入場動畫
如下,
<style>
標籤定義的三個類,
分別指定 入場動畫
的開始時
的透明度、
過程持續的時延
和 速度
(ease -- 緩慢)、
入場動畫的結束時
的透明度;
template
中,
使用<transition>
標籤對 包裹 要實現入場動畫
的DOM節點即可;
<head>
...
<style>
.v-enter-from{
opacity: 0;
}
.v-enter-active {
transition: opacity 3s ease;
}
.v-enter-to {
opacity: 1;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
<div>
<transition>
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
運行效果,實現入場動畫:
初始:
出場動畫
理同入場動畫,其中,
v-leave-from
表示 出場動畫
的開始時
的透明度、
v-leave-active
表示過程持續的時延
和 速度
(ease -- 緩慢)、
v-leave-to
表示出場動畫的結束時
的透明度;
其餘步驟 同入場動畫:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
.v-enter-from{
opacity: 0;
}
.v-enter-active {
transition: opacity 3s ease-out;
}
.v-enter-to {
opacity: 1;
}
.v-leave-from {
opacity: 1;
}
.v-leave-active {
transition: opacity 3s ease-in;
}
.v-leave-to {
opacity: 0;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
<div>
<transition>
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
運行效果:
初始:
出入場動畫同時實現時,可以簡化以上代碼
兩個v-xxx-active
可以寫到一起,
如果v-leave-from
指定的值與v-enter-to
相同(一般都是相同的),那也可以省略它;
以下代碼實現的效果,同上:
...
<style>
.v-enter-from{
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 3s ease-out;
}
.v-enter-to {
opacity: 1;
}
.v-leave-to {
opacity: 0;
}
</style>
...
出場入場幀動畫
準備好一個keyframes
,然後把它寫在v-xxx-active
中即可:
···
<style>
@keyframes shake {
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100% {
transform: translateX(50px);
}
}
.v-enter-active {
animation: shake 2s;
}
.v-leave-active {
animation: shake 2s;
}
</style>
···
使用name=
對動畫進行 片段式地 命名
可以在template
中,
在<transition>
標籤中,用name=
指定一個命名,
然後在style中定義css類時,
將之前的v-xxx-xxx
等定義符換成[命名]-xxx-xxx
即可:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
@keyframes shake {
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100% {
transform: translateX(50px);
}
}
.heheda-enter-active {
animation: shake 2s;
}
.heheda-leave-active {
animation: shake 2s;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
<div>
<transition name="heheda">
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
對動畫類的完全命名
即直接在template
中,在<transition>
標籤中,
使用[原css命名] = [新命名]
的方式,對整個CSS類取別名,
用的時候,直接使用新命名即可:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
@keyframes shake {
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100% {
transform: translateX(50px);
}
}
.hihi {
animation: shake 2s;
}
.byebye {
animation: shake 2s;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
<div>
<transition
enter-active-class="hihi"
leave-active-class="byebye">
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
關鍵代碼:
<!DOCTYPE html>
<html lang="en">
<head>
...
<style>
...
.hihi {
animation: shake 2s;
}
.byebye {
animation: shake 2s;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
...
<script>
...
template: `
...
<transition
enter-active-class="hihi"
leave-active-class="byebye">
<div v-if="show">heheda</div>
</transition>
...
</script>
運行效果同上例;
完全命名的方式 使得 容易接入 第三方庫
這裏以引入Animate.css
爲例;
官網:https://animate.style/
官網首頁如下,右側列表是各種動畫類型,點擊可以預覽效果:
官網簡略引導:
(如下可知,即
框架
已經把動畫
定義實現
好了,使用時只用直接使用
定義好的框架
的樣式命名
即可)彈跳效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<script src="https://unpkg.com/vue@next"></script>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"
/>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
<div>
<transition
enter-active-class="animate__animated animate__bounce"
leave-active-class="animate__animated animate__bounce">
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
閃爍效果:
template: `
<div>
<transition
enter-active-class="animate__animated animate__flash"
leave-active-class="animate__animated animate__flash">
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
注意以上案例,將v-if
換成v-show
也是可以正常運行的
區別在於隱藏組件的底層機制不同而已,
在博客筆記《Vue3 | 條件渲染 與 列表循環渲染》我們討論過這個事情;
顏色過渡和位移 動畫 結合
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
@keyframes shake {
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100% {
transform: translateX(50px);
}
}
.v-enter-from {
color: red;
}
.v-enter-active {
animation: shake 2s;
transition: all 2s ease-in;
}
.v-leave-active {
color: red;
animation: shake 2s;
transition: all 2s ease-in;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
<div>
<transition>
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
關鍵代碼:
入場,從紅色開始,到黑色(默認顏色);
出場,從黑色(默認顏色)開始,到紅色;
all
表示過渡特性
適配到 所用類型的動畫;
.v-enter-from {
color: red;
}
.v-enter-active {
animation: shake 2s;
transition: all 2s ease-in;
}
.v-leave-active {
color: red;
animation: shake 2s;
transition: all 2s ease-in;
}
控制組合動畫時長 以某一類型動畫的時間爲準
在<transition>
標籤上,
寫上type="transition"
,則組合動畫的時長 以過渡動畫 爲準;
寫上type="animation
,則組合動畫的時長 以普通類型動畫 爲準;
如下案例,寫上type="transition"
,
則組合動畫在 過渡動畫執行完畢(即3s)之後,
會立即停止 正在運行的 所有動畫:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
@keyframes shake {
0% {
transform: translateX(-100px);
}
50% {
transform: translateX(-50px);
}
100% {
transform: translateX(50px);
}
}
.v-enter-from {
color: red;
}
.v-enter-active {
animation: shake 6s;
transition: all 3s ease-in;
}
.v-leave-active {
color: red;
animation: shake 6s;
transition: all 3s ease-in;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
<div>
<transition type="transition">
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
控制組合動畫時長 以自定義的時長爲準
在<transition>
標籤上,
寫上:duration="[動畫時長 / ms]"
,則組合動畫的時長 以這裏定義的數據 爲準,
無論CSS類中,定義了多長的時延:
template: `
<div>
<transition :duration="1000">
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
分別 統一 出入場動畫的時延
:duration="[{enter: [入場動畫時延], leave:[出場動畫時延]}]"
template: `
<div>
<transition :duration="{enter: 1000, leave: 3000}">
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
禁用CSS動畫,使用JS動畫
-- 使用:css="false"
禁用CSS動畫,使得CSS動畫都失效(如果有定義的話);
-- @before-enter = "[方法名]"
定義 入場就緒
及 開始前
狀態的動畫回調方法;
-- @enter = "[方法名]"
定義 動畫運行時
狀態的 回調方法;
-- @after-enter="[方法名]"
定義 動畫結束時
狀態的 回調方法;
-- done();
通知架構動畫已經結束,可以回調 handleEnterEnd(el)
了;
【注意,以上是入場動畫
的鉤子回調,
把enter
換成leave
,即是對應的退場動畫
的鉤子回調】
如下代碼,
handleBeforeEnter(el)
指定 初始動畫顏色 爲 橙色;
handleEnterActive(el, done)
使得 動畫在 橙色 與 藍色之間 動態切換,
配合 setInterval(() => {}, 1000)
時隔一秒切換一次;
clearInterval(animation);
配合 setTimeout(() => {}, 5000)
使得5秒後關閉動畫;
隨後調用done();
通知架構 動畫已經結束,可以回調 handleEnterEnd(el)
了;
handleEnterEnd(el)
調試性地 彈出一個彈窗;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
},
handleBeforeEnter(el) {
el.style.color = "orange";
},
handleEnterActive(el, done) {
const animation = setInterval(() => {
const color = el.style.color;
if(color === "orange") {
el.style.color = 'blue';
} else {
el.style.color = 'orange';
}
}, 1000)
setTimeout(() => {
clearInterval(animation);
done();
}, 5000)
},
handleEnterEnd(el) {
alert("動畫結束!!!");
}
},
template: `
<div>
<transition
:css="false"
@before-enter = "handleBeforeEnter"
@enter="handleEnterActive"
@after-enter="handleEnterEnd">
<div v-if="show">heheda</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
運行效果:
最基本的 多個 單元素標籤 切換案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
},
},
template: `
<div>
<transition >
<div v-if="show">heheda</div>
<div v-else="show">lueluelue</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
帶上入場 退場 動畫的 兩個單元素標籤切換
-- css塊上面已經講過了,這裏主要是看mode="in-out"
;
這裏指定爲mode="in-out"
的話,
則切換時 先進行入場節點的 入場 及其 動畫【in】,
再進行退場節點 的 入場 及其 動畫【out】;
【缺點:入場 與 退場的節點,在入場動畫完畢前,會同框】
-- 如 指定爲mode="out-in"
,則順序與上相反;
【特性:入場 與 退場的節點 不會同框】
-- appear
特性:初始加載節點的時候,就會啓動入場動畫
,
沒有加這個標籤,入場動畫
需要觸發纔會啓動;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
.v-leave-to {
opacity: 0;
}
.v-enter-from {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 2s ease-in;
}
.v-leave-from,
.v-enter-to {
opacity: 1;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
},
},
template: `
<div>
<transition mode="out-in" appear>
<div v-if="show">heheda</div>
<div v-else="show">lueluelue</div>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
帶上入場 退場 動畫的 兩個組件 的切換
基於上例進行小改動即可,其原理是類似的,
以下代碼實現的效果 同上例;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
.v-leave-to {
opacity: 0;
}
.v-enter-from {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 2s ease-in;
}
.v-leave-from,
.v-enter-to {
opacity: 1;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const ComponentA = {
template: `<div>heheda</div>`
}
const ComponentB = {
template: `<div>lueluelue</div>`
}
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
},
},
components: {
'component-a': ComponentA,
'component-b': ComponentB,
},
template: `
<div>
<transition mode="out-in" appear>
<component-a v-if="show"/>
<component-b v-else="show"/>
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
<component>
組件佔位 + is屬性 + 雙向綁定特性 實現上例效果
-- data
字段 存儲要展示的子組件 的 組件名;
-- 點擊事件中 更改data
字段 以 更換 展示的子組件,
同時產生組件的 入場退場
,觸發相關動畫;
-- template
中 使用 <component>
標籤佔位,
使用is
控制要展示的組件, 指定值爲 data
字段;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
.v-leave-to {
opacity: 0;
}
.v-enter-from {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 2s ease-in;
}
.v-leave-from,
.v-enter-to {
opacity: 1;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const ComponentA = {
template: `<div>heheda</div>`
}
const ComponentB = {
template: `<div>lueluelue</div>`
}
const app = Vue.createApp({
data() {
return {
component : 'component-a'
}
},
methods: {
handleClick() {
if (this.component === 'component-a') {
this.component = 'component-b';
} else {
this.component = 'component-a';
}
},
},
components: {
'component-a': ComponentA,
'component-b': ComponentB,
},
template: `
<div>
<transition mode="out-in" appear>
<component :is="component">
</transition>
<button @click="handleClick">切換</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
運行效果同上例;
列表動畫
即列表增刪元素時,產生的
入場 和 出場動畫
;
主要是對itemView
、v-for
等標籤套上<transition-group>
這個特殊動畫標籤,
然後點擊事件時使用unshift
在隊頭添加元素,
其他的定義跟普通動畫差不多;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<style>
.v-enter-from {
opacity: 0;
transform: translateY(30px);
}
.v-enter-active {
transition: all .5s ease-in;
}
.v-enter-to {
opacity: 1;
transform: translateY(0);
}
.v-move {
transform: all .5s ease-in;
}
.list-item {
display: inline-block;
margin-right: 10px;
}
</style>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
list : [1, 2, 3]
}
},
methods: {
handleClick() {
this.list.unshift(this.list.length + 1);
},
},
template: `
<div>
<transition-group>
<span
class="list-item"
v-for="item in list"
:key = "item">{{item}}</span>
</transition-group>
<button @click="handleClick">增加</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
運行效果:
狀態動畫
顯示一個值【狀態】 到 另外一個值【狀態】 的變化過程,
類似於Android的ValueAnimator
;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World! heheheheheheda</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="heheApp"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
number: 1,
animateNumber: 1
}
},
methods: {
handleClick() {
this.number = 10;
const animation = setInterval(() => {
this.animateNumber += 1;
if(this.animateNumber >= this.number){
clearInterval(animation);
}
}, 100);
},
},
template: `
<div>
<span>{{animateNumber}}</span>
<button @click="handleClick">改變</button>
</div>`
});
const vm = app.mount('#heheApp');
</script>
</html>
運行效果: