iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
Modern Web

我的Vue學習筆記系列 第 13

Day13-元件漸變語動畫

漸變transition

這邊就像寫css一樣,只是要漸變的東西包在transition裡面,並到css下樣式。

  • 進場
    1. v-enter-from
    2. v-enter-active
    3. v-enter-to
  • 退場
    1. v-leave-from
    2. v-leave-active
    3. v-leave-to
<div style="height:120px">
    <transition>
        <div class="block" v-show="isShow">Hello</div>
    </transition>
</div>
<button @click="isShow=!isShow">Toggle</button>
const app = Vue.createApp({
    data() {
        return {
            isShow: true
        }
    }
});
.block {
    display: block;
    width: 150px;
    height: 100px;
    text-align: center;
    line-height: 100px;
    background-color: palevioletred;

}

.v-enter-active,
.v-leave-active {
    transition: opacity 1s;
}

.v-enter-from,
.v-leave-to {
    opacity: 0;
}

.v-enter-to,
.v-leave-from {
    opacity: 1;
}

自訂transition名稱

賦予name,把css中v-開頭改成和name一樣就可以自訂多個不同的效果

<transition name="fade">
    <div class="block" v-show="isShow">Hello</div>
</transition>
.fade-enter-active,
.fade-leave-active {
    transition: opacity 1s;
}

.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}

.fade-enter-to,
.fade-leave-from {
    opacity: 1;
}

條件與動態切換

繼上面的範例加上v-ifv-else就可以做條件的動態切換。

<div style="height:120px">
    <transition name="fade">
        <div class="block" v-if="isShow">no1</div>
        <div class="block" v-else>no2</div>
    </transition>
</div>
<button @click="isShow=!isShow">Toggle</button>

漸變效果的順序

transition中加上mode屬性

  1. in-out : 先執行新元素動畫,再移除現有的
  2. out-in(比較順暢) : 先移除現有的,再執行新元素動畫
<transition name="fade" mode="in-out">
    <div class="block" v-if="isShow">no1</div>
    <div class="block" v-else>no2</div>
</transition>

複數元素/元件的漸變渲染

若使用多個v-if就需要使用transition-group,兩個不一樣的地方就是內容物必須加入唯一值key才能正常動畫且不支援mode

<div class="mode">
    <label>
        <input v-model="demo" type="radio" value='A'>block A
    </label>
    <label>
        <input v-model="demo" type="radio" value='B'>block B
    </label>
    <label>
        <input v-model="demo" type="radio" value='C'>block C
    </label>
</div>
<transition-group name="fade">
    <div v-if="demo==='A'" :key="block-a" class="block">A block</div>
    <div v-if="demo==='B'" :key="block-b" class="block">B block</div>
    <div v-if="demo==='C'" :key="block-c" class="block">C block</div>
</transition-group>
const app = Vue.createApp({
    data() {
        return {
            demo: 'A',
            isShow: true
        }
    }
});

transition-group最常與v-for搭配尤其是列表顯示,範例中的tag屬性可以指定最外層由誰包覆。

Untitled

<button @click="add">Generate a random number</button>
<button @click="list.length=0">Remove all</button>
<transition-group tag="ul" class="number-list" name="list">
    <li v-for="(item,index) in list" :key="index" class="item">{{item}}</li>
</transition-group>
const app = Vue.createApp({
    data() {
        return {
            list: [1, 2, 3, 4, 5]
        }
    },
    methods: {
        add() {
            const randomNumber = Math.ceil(Math.random() * 100 + 1)
            this.list.push(randomNumber)
        }
    }
});
#app {
    position: relative;
    display: block;
    padding: 1rem;
    font-size: 1rem;
}
button {
    font-size: 1rem;
    margin-bottom: 1rem;
    margin-right: 1rem;
}
.number-list {
    overflow: hidden;
    padding: 0;
    margin-bottom: 1.5rem;
}
.number-list>li {
    display: block;
    float: left;
    width: 35px;
    height: 35px;
    text-align: center;
    line-height: 35px;
    background-color: #f00;
    color: #fff;
    margin-right: 1rem;
    margin-left: 0;
    margin-bottom: 1rem;
}
.list-enter-active,
.list-leave-active,
.list-move {
    transition: opacity 0.7s, transform 0.7s;
}
/*按remove時會回到最左邊淡出*/
.list-leave-active {
    position: absolute;
}
.list-enter-from {
    opacity: 0;
    transform: translateY(-20px);
}
.list-leave-to {
    opacity: 0;
    transform: translateY(20px);
}

除了上面漸變的class外,還有新增一個v-move,當元素改變定位時進行的動畫。

Untitled

<button @click="add">Add</button>
<button @click="shuffle">Shuffle</button>
<transition-group tag="ul" class="number-list" name="list">
    <li v-for="(item,index) in list" :key="item" class="item">{{item}}</li>
</transition-group>
const app = Vue.createApp({
    data() {
        return {
            list: [1, 2, 3, 4, 5, 6, 7, 8, 9],
            nextNum: 10
        }
    },
    methods: {
        randomIndex() {
            return Math.floor(Math.random() * this.list.length)
        },
        add() {
            this.list.splice(this.randomIndex(), 0, this.nextNum++)
        },
        shuffle() {
            this.list.sort(() => Math.random() - 0.5)
        }
    }
});
.list-move {
    transition: all 5s ease
}

上一篇
Day12-slot插槽
下一篇
Day14-Vue CLI 介紹
系列文
我的Vue學習筆記30

尚未有邦友留言

立即登入留言