vue 在插入, 更新或者移除 DOM 时, 提供多种不同方式的应用过渡效果.
包括以下工具:
a. 在 CSS 过渡和动画中自动应用 class
b. 可以配合使用第三方 css 动画库, 如 Animate.css
c. 在过渡钩子函数中使用 JavaScript 直接操作 DOM
d. 可以配合使用第三方 JavaScript 动画库, 如 Velocity.js
Vue 提供了 transition 的封装组件, 下列情形中, 可以给任何元素和组件添加进入 / 离开过渡
a. 条件渲染(使用 v-if)
b. 条件展示(使用 v-show)
c. 动态组件
d. 组件根节点
例如:
- <style>
- .fade-enter-active,.fade-leave-active{
- transition: opacity .5s;
- }
- .fade-enter,.fade-leave-to{
- opacity:0
- }
- </style>
- <div id='demo'>
- <button v-on:click="show =! show">toggle</button>
- <transition name='fade'>
- <p v-if='show'>hello</p>
- </transition>
- </div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
- <script>
- new Vue({
- el: '#demo',
- data: {
- show: true
- }
- });
- </script>
当插入或删除包含在 transition 组件中的元素时, Vue 将会做以下处理:
a. 自动嗅探目标元素是否应用了 css 过渡或动画, 如果是, 在恰当的时机添加 / 删除 css 类名
b. 如果过渡组件提供了 JavaScript 的钩子函数, 这些钩子函数会在恰当的时机被调用
c. 如果没有找到钩子函数, 也没有检测到 css 过渡或动画, DOM 操作 (插入 / 删除) 在下一帧中立即执行.
1. 过渡的类名
在进入 / 离开的过渡中, 会有 6 个 class 切换.
a. v-enter: 定义进入过渡的开始状态. 在元素被插入之后的下一帧移除
b. v-enter-active: 定义进入过渡生效时的状态. 在整个进入过渡的阶段中应用, 在元素被插入之前生效, 在过渡 / 动画完成之后移除. 这个类可以被用来定义进入过渡的时间, 延迟和曲线函数
c. v-enter-to: 定义进入过渡的结束状态. 在元素被插入之后的下一帧生效(与此同时 v-ennter 被移除), 在过渡 / 动画完成之后移除
d. v-leave: 定义离开过渡的开始状态. 在离开过渡被触发时立刻生效, 下一帧被移除.
e. v-leave-active: 定义离开过渡生效时的状态. 在整个离开过渡的阶段中应用, 在离开过渡触发时立刻生效, 在过渡 / 动画完成后移除. 这个类可以被用来定义离开过渡的过程时间, 延迟和曲线函数.
f. v-leave-to: 定义离开过渡的结束状态. 在离开过渡被触发后下一帧生效(与此同时 v-leave 被删除), 在过渡 / 动画完成之后移除
对于这些在过渡中切换的类名来说, 如果使用的是一个没有名字的 transition , 则 v- 会替换这些类名的默认前缀. 如果 transition 有 name='my-transition' 属性, 则 v-enter 会替换为 my-transition-enter.
2. CSS 过渡
- <style>
- .slide-fade-enter-active {
- transition: all .3s ease;
- }
- .slide-fade-leave-active {
- transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
- }
- .slide-fade-enter,
- .slide-fade-leave-to{
- transform: translateX(10px);
- opacity: 0;
- }
- </style>
- <div id='demo'>
- <button v-on:click="show =! show">toggle</button>
- <transition name="slide-fade">
- <p v-if="show">hello</p>
- </transition>
- </div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
- <script>
- new Vue({
- el: '#demo',
- data: {
- show: true
- }
- });
- </script>
3.CSS 动画
CSS 动画用法同 CSS 过渡, 区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除, 而是在 animationend 事件触发时删除.
- <style>
- .bounce-enter-active{
- animation: bounce-in .8s;
- }
- .bounce-leave-active{
- animation:bounce-in .8s reverse;
- }
- @keyframes bounce-in{
- 0%{
- transform: scale(0);
- }
- 50%{
- transform: scale(1.5)
- }
- 100%{
- transform:scale(1)
- }
- }
- </style>
- <div id='demo'>
- <button v-on:click="show =! show">toggle</button>
- <transition name="bounce">
- <p v-if="show">hello</p>
- </transition>
- </div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
- <script>
- new Vue({
- el: '#demo',
- data: {
- show: true
- }
- });
- </script>
4. 自定义过渡的类名
可以通过以下特性来自定义过渡类名:
- a. enter-class
- b. enter-active-class
- c. enter-to-class
- d. leave-class
- e. leave-active-class
- f. leave-to-class
他们的优先级高于普通的类名, 这对于 Vue 的过渡系统和其他第三方 CSS 动画库, 如 Animate 结合使用十分有用.
例如:
- <link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
- <div id="example">
- <button @click="show = !show">
- Toggle render
- </button>
- <transition
- name="custom-classes-transition"
- enter-active-class="animated tada"
- leave-active-class="animated bounceOutRight"
- >
- <p v-if="show">hello</p>
- </transition>
- </div>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
- <script>
- new Vue({
- el: '#example',
- data: {
- show: true
- }
- })
- </script>
5. 同时使用过渡和动画
Vue 为了知道过渡的完成, 必须设置相应的事件监听器. 它可以是 transition 或者 animateionend, 这取决于给元素应用的 css 规则. 如果使用其中的任何一种, Vue 能自动识别类型并设置监听.
在一些场景中, 需要给同一个元素同时设置两种过渡动效, 比如 animation 很快的触发并完成了, 而 transition 效果还没有结束. 这种情况中, 需要使用 type 特性并设置 animation 或 transition 来明确声明需要 Vue 监听的类型.
6. 显性的过渡持续时间
设置 transition 组件上的 duration 属性定制一个显性的过渡持续时间(以毫秒计):
<transition :duration="1000">...</transition>
可以定制进入和移出的持续时间:
<transition :duration='{enter: 500,leave:800}'>...</transition>
7.JavaScript 钩子
可以在属性中声明 JavaScript 钩子:
- <div id='example'>
- <button @click="show = !show">Toggle</button>
- <transition
- v-on:before-enter="beforeEnter" v-on:enter="enter"
- v-on:leave="leave"
- v-bind:css="false">
- <p v-if="show">
- Demo
- </p>
- </transition>
- </div>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
- <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
- <script>
- new Vue({
- el: '#example',
- data: {
- show: false
- },
- methods: {
- beforeEnter: function (el) {
- el.style.opacity = 0;
- el.style.transformOrigin = 'left';
- },
- enter: function (el, done) {
- Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
- Velocity(el, { fontSize: '1em' }, { complete: done })
- },
- leave: function (el, done) {
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
- Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
- Velocity(el, {
- rotateZ: '45deg',
- translateY: '30px',
- translateX: '30px',
- opacity: 0
- }, { complete: done })
- }
- }
- })
- </script>
当只用 JavaScript 过渡的时候, 在 enter 和 leave 中, 回调函数 done 是必须的. 否则, 他们会被同步调用, 过渡会立即完成.
推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css='fasle', Vue 会跳过 css 的检测. 这也可以避免过渡过程中 css 的影响.
来源: http://www.qdfuns.com/article/46690/e9f43ecaa2d5942594d59bd11eb404d1.html