likes
comments
collection
share

transition实现单元素/单组件的过渡和动画

作者站长头像
站长
· 阅读数 15

Vue中使用css做动画和过渡

单元素/单组件的入场和出场过渡

什么是单元素/单组件

形如下面这样,模板中根div中只有一个div,叫单元素。同理,如果把这个div换成一个组件,那么就是一个单组件

template: `
    <div>
        // 单元素 
        <div class="transition" :style="styleObj">hello world</div>
        <button @click="handleClick">切换</button>
    </div>
 `
 

什么是入场/出场

当页面中的DOM元素从显示状态到隐藏状态叫“入场”,当页面中的DOM元素从隐藏状态到显示状态叫“入场”

transition标签搭配固定的class,完成入场和出场过渡

敲代码

 <style>
    .v-enter-from{
        opacity: 0;
    }
    .v-enter-active{
        transition: opacity 2s ease-in-out;
    }
    .v-enter-to{
        opacity: 1;
    }
    .v-leave-from{
        opacity: 1;
    }
    .v-leave-active{
        transition: opacity 2s ease-in-out;
    }
    .v-leave-to{
        opacity: 0;
    }
 </style>
 
 const app = Vue.createApp({
        data() {
            return {
                show: false
            }
        },
        methods: {
            handleClick() {
              this.show = !this.show
            }
        },
        template: `
        <div>
            <transition>
                <div v-if="show">hello world</div>
            </transition>
            <button @click="handleClick">切换</button>
        </div>
        `
    })

    const vm = app.mount('#root')

运行结果

备注

  • v-enter-from: 入场动画的初始状态
  • v-enter-active: 设定整个入场动画的状态具体如何展示,如,动画持续的时间,过渡的动画类型
  • c-enter-to: 入场动画的结束状态
  • v-leave-from:出场动画的初始状态
  • v-leave-active:设定整个出场动画的状态具体如何展示,如,动画持续的时间,过渡的动画类型
  • v-leave-to:出场动画的结束状态

transition实现单元素/单组件的过渡和动画

简写

不管是出场还是出场,由于默认opacity是1,可以省略不写,

因此下面的状态可以不写:

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

实现动画

敲代码

@keyframes shake{
    0% {
        transform: translateX(-100px);
    }
    50% {
        transform: translateX(-50px);
    }
    100%{
        transform: translateX(50px);
    }
}
.v-enter-active{
    animation: shake 3s;
}
.v-leave-active{
    animation: shake 3s;
}

const app = Vue.createApp({
    data() {
        return {
            show: false
        }
    },
    methods: {
        handleClick() {
          this.show = !this.show
        }
    },
    template: `
    <div>
        <transition>
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleClick">切换</button>
    </div>
    `
})

  const vm = app.mount('#root')

运行结果

transition实现单元素/单组件的过渡和动画

备注

实现动画效果,相比过渡效果更简单一点,只依赖2个样式 v-leave-activev-enter-active

使用transition上的name属性自定义与之搭配的class名的前缀

前面同transtion标签搭配的样式名都是固定的,如:v-enter-fromv-enter-activec-enter-to等都是叫v-xxx

其实我们也可以自定义命名这些样式名

我们只需要给transtion标签,加上name属性,这样与之搭配的样式名就以这个name属性对应的值开头了

敲代码

@keyframes shake{
    0% {
        transform: translateX(-100px);
    }
    50% {
        transform: translateX(-50px);
    }
    100%{
        transform: translateX(50px);
    }
}
.hello-enter-active{
    animation: shake 3s;
}
.hello-leave-active{
    animation: shake 3s;
}

const app = Vue.createApp({
    data() {
        return {
            show: false
        }
    },
    methods: {
        handleClick() {
          this.show = !this.show
        }
    },
    template: `
    <div>
        <transition name="hello">
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleClick">切换</button>
    </div>
    `
})

const vm = app.mount('#root')

直接自定义与transition搭配的所有的class名

具体方法是:在transtion标签上使用诸如:

enter-active-class="xxx"leave-active-class="yyy"......

那么在定义class的时候就直接写.xxx{} .yyy{}就可以定义动画的样式了

敲代码

 @keyframes shake{
    0% {
        transform: translateX(-100px);
    }
    50% {
        transform: translateX(-50px);
    }
    100%{
        transform: translateX(50px);
    }
}
.hello{
    animation: shake 3s;
}
.bye{
    animation: shake 3s;
}
const app = Vue.createApp({
    data() {
        return {
            show: false
        }
    },
    methods: {
        handleClick() {
          this.show = !this.show
        }
    },
    template: `
    <div>
        <transition 
          enter-active-class="hello"
          leave-active-class="bye"
        >
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleClick">切换</button>
    </div>
    `
})

const vm = app.mount('#root')

自定义class名的好处

使用自定义class的好处就是可以做些更复杂的css动画,而却可以使用第三方的css库

eg: 我们可以使用animate.css库实现有趣的动画效果

如何与动画库结合使用呢?

  1. 首先我们自己就不要再定义动画效果了,直接使用动画库中提供的动画
  2. 接着我们只需要在入场和出场动画执行过程中使用自定义样式指定animate为我们提供好的class即可: enter-active-class='animate__animated animate__bounce' leave-active-class='animate__animated animate__bounce'
  3. 当然animate库中还有其他动画,不止animate__bounce这样的弹跳动画,当然不论添加什么动画class,animate__animatedclass是不需要有的

敲代码

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">hello world</div>
        </transition>
        <button @click="handleClick">切换</button>
    </div>
    `
})

const vm = app.mount('#root')

运行结果

transition实现单元素/单组件的过渡和动画

动画的同时有过渡

敲代码

@keyframes shake{
    0% {
        transform: translateX(-100px);
    }
    50% {
        transform: translateX(-50px);
    }
    100%{
        transform: translateX(50px); 
    }
}
.v-enter-from{
    color: red;
}
.v-enter-active{
    animation: shake 3s;
    transition: all 3s ease-in;
}
.v-enter-to{
    color: green;
}
.v-leave-from{
    color: green;
}
.v-leave-active{
    animation: shake 3s;
    transition: all 3s ease-out;
} 
.v-leave-to{
    color: red;
}

const app = Vue.createApp({
    data() {
        return {
            show: false
        }
    },
    methods: {
        handleClick() {
            this.show = !this.show
        }
    },
    template: `
    <div>
        <transition>
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleClick">切换</button>
    </div>
    `
})

运行结果

transition实现单元素/单组件的过渡和动画

动画和过渡时间不一致时,指定以某个的时间为主

比如:动画效果执行3s,过渡效果执行10秒,现在我们想以动画效果为主,3s动画效果结束后,过渡效果也跟着结束

在transition标签上使用type="animation"的方式,指定以动画时间为主

敲代码

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

const vm = app.mount('#root')

运行结果

不加type="animation"时的效果:颜色过渡10s

transition实现单元素/单组件的过渡和动画

type="animation"时的效果:颜色过渡3秒完成

transition实现单元素/单组件的过渡和动画

使用:duration强制指定动画和过渡持续时间

1. :duration为数字,:duration="1000"指定动画和过渡持续时间

敲代码

const app = Vue.createApp({
    data() {
        return {
            show: false
        }
    },
    methods: {
        handleClick() {
            this.show = !this.show
        }
    },
    template: `
    <div>
        <transition :duration="1000">
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleClick">切换</button>
    </div>
    `
})

const vm = app.mount('#root')

运行结果

transition实现单元素/单组件的过渡和动画

2. duration为对象,:duration="{}"指定动画和过渡的入场时间和出场时间

敲代码

const app = Vue.createApp({
    data() {
        return {
            show: false
        }
    },
    methods: {
        handleClick() {
            this.show = !this.show
        }
    },
    template: `
    <div>
        <transition :duration="{enter: 1000,leave: 3000}">
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleClick">切换</button>
    </div>
    `
})

const vm = app.mount('#root')

运行结果

transition实现单元素/单组件的过渡和动画

Vue中使用JS做动画和过渡

具体方法是:

  1. 使用:css="false" 表示不使用css做动画
  2. Vue中提供了一些钩子(类似生命周期函数,某一时刻自动执行的函数)供我们使用

敲代码

const app = Vue.createApp({
    data() {
        return {
            show: false
        }
    },
    methods: {
        handleClick() {
            this.show = !this.show
        },
        handleBeforeEnter(el){
            el.style.color = 'red'
        },
        handleEnterActive(el,done){
            const animation = setInterval(() => {
                const color = el.style.color
                if(color === 'red'){
                    el.style.color = 'green'
                }else{
                    el.style.color = 'red'
                }
            }, 1000);
            setTimeout(() => {
               clearInterval(animation)
               done()
            }, 3000);
        }

    },
    template: `
    <div>
        <transition 
          :css = "false"
          @before-enter = "handleBeforeEnter"
          @enter = "handleEnterActive"
          @after-enter = "handleEnterEnd"
        >
            <div v-if="show">hello world</div>
        </transition>
        <button @click="handleClick">切换</button>
    </div>
    `
})

const vm = app.mount('#root')

运行结果

transition实现单元素/单组件的过渡和动画

备注

  • @before-enter="xxx",在入场开始之前自动执行的函数,函数xxx中可以使用参数el接收vue帮我们传递过来的DOM元素
  • @enter="xxx",动画开始时自动执行的函数,函数xxx,接收2个参数,一个是DOM元素el,另外一个是done,它的作用是告诉@after-enter中的函数,当前动画已结束,当执行done()后 @after-enter才能感知到动画结束了,才能执行动画结束后的逻辑
  • @after-enter="xxx",动画结束时自动执行的函数,函数xxx中接收1个参数el
  • 同理出场动画的钩子:@before-leave="xxx"@leave="xxx"@after-leave="xxx"
转载自:https://juejin.cn/post/7241749527987650620
评论
请登录