如何利用vue實現css過渡和動畫

一、過渡和動畫的區別

過渡:通常用來表示元素上屬性狀態的變化。

動畫:通常用來表示元素運動的情況。

二、使用Vue實現基礎得css過渡與動畫

1. 動畫

/* css */
@keyframes leftToRight {
    0% {
        transform: translateX(-100px);
    }
    50% {
        transform: translateX(-50px);
    }
    100% {
        transform: translateX(0);
    }
}
.animation {
    animation: leftToRight 3s;
}
// js
const app = Vue.createApp({
    data() {
        return {
            animate: {
                animation: true
            }
        }
    },
    methods: {
        handleClick(){
            this.animate.animation = !this.animate.animation
        }
    },
    template: `
        <div :class='animate'>hello</div>
        <button @click='handleClick'>切換</button>
    `
});

2. 過渡

/* css */
.transition {
    transition: background-color 3s linear 0s;
}
 
.gold {
    background-color: gold;
}
 
.cyan {
    background-color: cyan;
}
// js
const app = Vue.createApp({
    data() {
        return {
            animate: {
                transition: true,
                gold: true,
                cyan: false
            }
        }
    },
    methods: {
        handleClick() {
            this.animate.gold = !this.animate.gold;
            this.animate.cyan = !this.animate.cyan;
        }
    },
    template: `
        <div :class='animate'>hello</div>
        <button @click='handleClick'>切換</button>
    `
});

以上是通過設置class屬性實現的,同樣通過設置style屬性也可以實現:

/* css */
.transition {
    transition: background-color 3s linear 0s;
}
// js
data() {
    return {
        transition: 'transition',
        styleObject: {
            backgroundColor: 'gold'
        }
    }
},
methods: {
    handleClick() {
        if(this.styleObject.backgroundColor === 'gold'){
            this.styleObject.backgroundColor = 'cyan';
        }else{
            this.styleObject.backgroundColor = 'gold';
        }
    }
},
template: `
    <div :class='transition' :style='styleObject'>hello</div>
    <button @click='handleClick'>切換</button>
`

三、使用transition標簽實現單元素/組件的過渡和動畫效果

1. transition 的基本介紹

  • <transition> 元素作為單個元素/組件的過渡效果。
  • <transition> 隻會把過渡效果應用到其包裹的內容上,而不會額外渲染 DOM 元素,也不會出現在可被檢查的組件層級中

2. transition 的過渡class

在進入/離開的過渡中,會有 6 個 class 切換:

  • v-enter-from:定義進入過渡的開始狀態。在元素被插入之前生效,在元素被插入之後的下一幀移除。
  • v-enter-active:定義進入過渡生效時的狀態。在整個進入過渡的階段中應用,在元素被插入之前生效,在過渡/動畫完成之後移除。這個類可以被用來定義進入過渡的過程時間,延遲和曲線函數。
  • v-enter-to:定義進入過渡的結束狀態。在元素被插入之後下一幀生效 (與此同時 v-enter-from 被移除),在過渡/動畫完成之後移除。
  • v-leave-from:定義離開過渡的開始狀態。在離開過渡被觸發時立刻生效,下一幀被移除。
  • v-leave-active:定義離開過渡生效時的狀態。在整個離開過渡的階段中應用,在離開過渡被觸發時立刻生效,在過渡/動畫完成之後移除。這個類可以被用來定義離開過渡的過程時間,延遲和曲線函數。
  • v-leave-to:離開過渡的結束狀態。在離開過渡被觸發之後下一幀生效 (與此同時 v-leave-from 被刪除),在過渡/動畫完成之後移除。

3. 過渡示例

將需要過渡的元素使用transition標簽包裹。設置過渡需要的class,可從以上六種class中選擇。

/* css */
/* .v-enter-from {
    opacity: 0;
}
.v-enter-active {
    transition: opacity 1s ease;
}
.v-enter-to {
    opacity: 1;
}
.v-leave-from {
    opacity: 1;
}
.v-leave-active {
    transition: opacity 1s ease;
}
.v-leave-to {
    opacity: 0;
} */
/* 簡寫 */
.v-enter-from, .v-leave-to{
    opacity: 0;
}
.v-enter-active, .v-leave-active{
    transition: opacity 1s ease;
}
// js
const app = Vue.createApp({
    data() {
        return {
            show: true
        }
    },
    methods: {
        handleClick() {
            this.show = !this.show;
        }
    },
    template: `
        <transition>
            <div v-if='show'>hello</div>
        </transition>
        <button @click='handleClick'>切換</button>
    `
});

4. 動畫示例

使用動畫效果隻需要修改css部分,js部分功能不變。

/* css */
@keyframes shake-in {
    0% {
        transform: translateX(-50px);
    }
    50% {
        transform: translateX(50px);
    }
    100% {
        transform: translateX(0px);
    }
}
@keyframes shake-out {
    0% {
        transform: translateX(50px);
    }
    50% {
        transform: translateX(-50px);
    }
    100% {
        transform: translateX(0px);
    }
}
.v-enter-active{
    animation: shake-in 1s ease-in;
}
.v-leave-active{
    animation: shake-out 1s ease-in-out;
}

5. transition的name屬性

  • name – string :用於自動生成 CSS 過渡類名,不寫默認是v。
  • name設置為hy,對應的class名稱也要改為hy開頭。
  • // js
    <transition name='hy'>
        <div v-if='show'>hello</div>
    </transition>

/* css */
.hy-enter-from, .hy-leave-to{
    opacity: 0;
}
.hy-enter-active, .hy-leave-active{
    transition: opacity 1s ease;
}

6. 自定義過渡類名

我們可以通過以下 attribute 來自定義過渡類名:

  • enter-from-class
  • enter-active-class
  • enter-to-class
  • leave-from-class
  • leave-active-class
  • leave-to-class

他們的優先級高於普通的類名,這對於 Vue 的過渡系統和其他第三方 CSS 動畫庫,如 Animate.css. 結合使用十分有用。

// 首先引入樣式文件
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" rel="external nofollow"  />
 
const app = Vue.createApp({
    data() {
        return {
            show: true
        }
    },
    methods: {
        handleClick() {
            this.show = !this.show;
        }
    },
    // 以自定義過渡類名的方式去添加動畫樣式
    template: `
        <transition name='hy' 
        enter-active-class='animate__animated animate__bounce'
        leave-active-class='animate__animated animate__bounce'>
            <div v-if='show'>hello</div>
        </transition>
        <button @click='handleClick'>切換</button>
    `
});

7. 同時設置過渡和動畫

  • 在一些場景中,你需要給同一個元素同時設置過渡和動畫,比如 animation 很快的被觸發並完成瞭,而 transition 效果還沒結束。
  • 在這種情況中,你就需要使用 type attribute 並設置 animation 或 transition 來明確聲明你需要 Vue 監聽的類型。
  • type – string。指定過渡事件類型,偵聽過渡何時結束。有效值為 “transition” 和 “animation”。默認 Vue.js 將自動檢測出持續時間長的為過渡事件類型。

在transition時間更長時,使用type=‘transiton’的效果:

可以發現animation先完成,但transition並沒有終止會一致執行完,元素才消失。

/* css */
@keyframes shake-in {
    0% {
        transform: translateX(-50px);
    }
 
    50% {
        transform: translateX(50px);
    }
 
    100% {
        transform: translateX(0px);
    }
}
 
@keyframes shake-out {
    0% {
        transform: translateX(50px);
    }
 
    50% {
        transform: translateX(-50px);
    }
 
    100% {
        transform: translateX(0px);
    }
}
 
.v-enter-from,
.v-leave-to {
    color: red;
}
 
.v-enter-active {
    animation: shake-in 1s ease-in;
    transition: color 3s ease-in;
}
 
.v-enter-to, .v-leave-from {
    color: green;
}
 
.v-leave-active {
    animation: shake-out 1s ease-in-out;
    transition: color 3s ease-in-out;
}
// js
const app = Vue.createApp({
    data() {
        return {
            show: true
        }
    },
    methods: {
        handleClick() {
            this.show = !this.show;
        }
    },
    template: `
        <transition type='transition'>
            <div v-if='show'>hello</div>
        </transition>
        <button @click='handleClick'>切換</button>
    `
});

 

在transition時間更長時,使用type=‘animation‘的效果:

  • 可以發現animation完成後,transition也會立即終止,元素也消失瞭。
<transition type='animation'>
    <div v-if='show'>hello</div>
</transition>

8. duration 屬性

  • duration – number | { enter: number, leave: number }:指定過渡的持續時間。
  • 比css中設置的時間優先級更高。
  • 單位是:ms。
<transition :duration='100' >
    <div v-if='show'>hello</div>
</transition >

你也可以定制進入和移出的持續時間:

<transition :duration='{ enter: 1000, leave: 3000 }' >
    <div v-if='show'>hello</div>
</transition >

9. 使用js實現動畫

  • 當隻用 JavaScript 過渡的時候,在 enter 和 leave 鉤中必須使用 done 進行回調。否則,它們將被同步調用,過渡會立即完成。
  • 添加 :css=”false”,也會讓 Vue 會跳過 CSS 的檢測,除瞭性能略高之外,這可以避免過渡過程中 CSS 規則的影響。

想要用js實現動畫,可以在transition的 attribute 中聲明 JavaScript 鉤子:

@before-enter=”beforeEnter” 進入過渡前
@enter=”enter” 進入過渡時
@after-enter=”afterEnter” 進入過渡後
@enter-cancelled=”enterCancelled” 進入過渡被打斷時
@before-leave=”beforeLeave” 離開過渡前
@leave=”leave” 離開過渡時
@after-leave=”afterLeave” 離開過渡後
@leave-cancelled=”leaveCancelled” 離開過渡被打斷時
const app = Vue.createApp({
    data() {
        return {
            show: true
        }
    },
    methods: {
        handleClick() {
            this.show = !this.show;
        },
        handleBeforeEnter(el){
            el.style.color = 'red';
        },
        handleEnter(el, done){
            const timer = setInterval(()=>{
                if(el.style.color === 'red'){
                    el.style.color = 'blue';
                }else{
                    el.style.color = 'red';
                }
            }, 1000);
            setTimeout(()=>{
                clearInterval(timer);
                // 動畫結束標志
                // 不執行done()的話,handleAfterEnter不會執行
                done();
            }, 3000)
        },
        handleAfterEnter(el){
            console.log('success');;
        }
    },
    template: `
        <transition :css='false'
        @before-enter='handleBeforeEnter'
        @enter='handleEnter'
        @after-enter='handleAfterEnter'
        >
            <div v-if='show'>hello</div>
        </transition>
        <button @click='handleClick'>切換</button>
    `
});

// js
const app = Vue.createApp({
    components: ['item-a', 'item-b'],
    data() {
        return {
            component: 'item-a'
        }
    },
    methods: {
        handleClick() {
            if (this.component === 'item-a') {
                this.component = 'item-b';
            } else {
                this.component = 'item-a';
            }
        }
    },
    template: `
        <transition mode='out-in' appear>
            <component :is='component' />
        </transition>
        <button @click='handleClick'>切換</button>
    `
});
app.component('item-a', {
    template: `<div>hello</div>`
});
app.component('item-b', {
    template: `<div>bye</div>`
});

四、組件和元素切換動畫的實現

  • mode – string 控制離開/進入過渡的時間序列。
  • 有效的模式有 先出後進: “out-in” 和 先進後出:”in-out”;默認同時進行。
  • 可以通過 appear attribute 設置節點在初始渲染的過渡。
/* css */
.v-enter-from,
.v-leave-to {
    opacity: 0;
}
 
.v-enter-active,
.v-leave-active {
    transition: opacity 1s ease-in;
}
 
.v-enter-to,
.v-leave-from {
    opacity: 1;
}
// js
const app = Vue.createApp({
    components: ['item-a', 'item-b'],
    data() {
        return {
            component: 'item-a'
        }
    },
    methods: {
        handleClick() {
            if (this.component === 'item-a') {
                this.component = 'item-b';
            } else {
                this.component = 'item-a';
            }
        }
    },
    template: `
        <transition mode='out-in' appear>
            <component :is='component' />
        </transition>
        <button @click='handleClick'>切換</button>
    `
});
app.component('item-a', {
    template: `<div>hello</div>`
});
app.component('item-b', {
    template: `<div>bye</div>`
});

五、列表動畫

  • 使用 <transition-group> 組件,可以同時渲染整個列表。
  • 內部元素總是需要提供唯一的 key attribute 值。
  • CSS 過渡的類將會應用在內部的元素中,而不是這個組/容器本身。
  • <transition-group> 組件還有一個特殊之處。不僅可以進入和離開動畫,還可以改變定位。要使用這個新功能隻需使用新增的 v-move 類。
/* css */
.inline-block {
    display: inline-block;
    margin-right: 10px;
}
 
.v-enter-from,
.v-leave-to {
    opacity: 0;
    transform: translateY(30px);
}
 
.v-enter-active {
    transition: all 1s ease;
}
 
.v-leave-active {
    position: absolute;
}
 
.v-move {
    transition: all 1s ease;
}

六、狀態動畫

對於數據元素本身而言,通過數字和運算、顏色的顯示、SVG 節點的位置、元素的大小和其他的 property 這些屬性的變化,同樣可以實現動畫的效果。

數字變化示例:

const app = Vue.createApp({
    data() {
        return {
            number: 1
        }
    },
    methods: {
        handleClick() {
            const timer = setInterval(() => {
                if (this.number >= 10) {
                    clearInterval(timer)
                }else{
                    this.number++;
                }
            }, 100);
        }
    },
    template: `
        <div>{{number}}</div>
        <button @click='handleClick'>增加</button>
    `
});

 

總結

到此這篇關於如何利用vue實現css過渡和動畫的文章就介紹到這瞭,更多相關vue實現css過渡和動畫內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: