Vue 2.0 过度&动画部分

236 阅读5分钟

过渡与动画


进入/离开&列表过渡

  • 单元素/组件的过渡知识点

Vue 提供了 tansition 的封装组件,在模板中使用,在条件渲染(使用 v-if)、条件展示(使用 v-show)、动态组件组件根节点的情形下,可以给任何元素和组件添加进入/离开过渡

当插入或删除包含在 tansition 组件中的元素时,Vue会做以下的处理:

  1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名
  2. 如果过渡组件提供了 JavaScript钩子函数,这些钩子函数会在恰当的时机被调用
  3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画, DOM 操作会在下一帧立即执行
  • 过渡的类名

    v-enter: 定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除

    v-enter-active: 定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数

    v-enter-to:定义进入过渡的结束状态。在元素被插入之后下一帧生效,在过渡/动画完成之后移除

    v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除

    v-leave-active: 定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数

    v-leave-to:定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效,在过渡/动画完成之后移除

  • CSS 动画注意点

    CSS 动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件(动画完成触发的事件)触发时删除

  • 自定义过渡的类名

    可以通过以下的属性来自定义过渡类名

    enter-class enter-active-class enter-to-class leave-class leave-active-class leave-to-class

    自定义过渡类名的优先级会高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库的结合使用十分有效

  • 同时使用过渡和动画的注意点

    在给同一个元素同时设置两种过渡动画效果时,需要使用 type 属性并设置 animationtansition 来明确声明需要 Vue 监听的类型

  • 显性的过渡持续事件

    在嵌套的内部元素相比于过渡效果的根元素有延迟的或更长的过渡效果的情况下,可以用 transitiion 组件上的 duration prop 定制一个显性的过渡持续时间(以毫秒计)

    <transition :duration="{ enter: 500, leave: 800 }">...</transition>
    
  • JavaScript钩子

    可以在 attribute 中声明 JavaScript 钩子

    <transition
        v-on:before-enter="beforeEnter(el)"
        v-on:enter="enter(el, done)"    //回调函数 done 是可选的 
        v-on:after-enter="afterEnter(el)" 
        v-on:enter-cancelled="enterCancelled(el)"
        v-on:before-leave="beforeLeave(el)" 
        v-on:leave="leave(el,done)"
        v-on:after-leave="afterLeave(el)"
        v-on:leave-cancelled="leaveCancelled(el)"    // leaveCancelled 只用于 v-show 中 
    > 
        <!-- ... --> 
    </transition>
    

    这些钩子函数可以结合 CSS transitions/animations 使用,也可以单独使用

    注意: 当只用 JavaScript 过渡的时候,enterleave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。如果仅使用 JavaScript 过渡的元素添加 v-bind:css = "false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响

  • 初始渲染的过渡

    可以通过 appear 属性设置节点在初始渲染的过渡

    <transition appear>
        <!-- ... -->
    </transition>
    
  • 多个元素的过渡注意点

    当有相同标签名的元素切换时,需要通过 key 属性设置唯一的值来标记让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。在给 transtion 组件中的多个元素设置 key 是一个更好的实践

    注意: <transition> 的默认行为-进入和离开同时发生

    这样的情况不能满足所有要求,Vue 提供了过渡模式

    in-out: 新元素先进行过渡,完成之后当前元素过渡离开

    out-in: 当前元素先进行过渡,完成之后新元素过渡进入

    <transition name="fade" mode="out-in"> 
        <!-- ... the buttons ... -->
    </transition>
    
  • 列表过渡注意点

    使用 <transition-group> 组件来渲染整个列表

    <transition-group> 注意点:

    1. <transition> 在最终渲染时不会解析到标签中,但是 <transition-group> 会被解析成一个 <span>,也可以通过 tag 属性来更换为其他元素
    2. 过渡模式在 <transition-group> 中不可用,因为不会再相互切换特有的元素
    3. 内部元素总是需要提供唯一的 key 属性值来确保过渡的正常使用
    4. CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身
  • 列表的排序过渡知识点

    <transition-group> 组件可以改变定位,使用 v-move class,它会在元素的改变定位的过程中应用,使用 v-move 可以让位置的改变变得平滑,原因是 Vue 使用了一个叫 FLIP 简单的动画队列,使用 transform 将元素从之前的位置平滑过渡新的位置 v-move 对于设置古欧的切换时机和过渡曲线非常有用,使用如下所示:

    .flip-list-move { 
        transition: transform 1s; 
    }
    

    注意: 使用 FLIP 过渡的元素不能设置为 display:inline。作为替代方案,可以设置为 display: inline-block 或者放置为 flex

  • 可复用的过渡知识点

    过渡可以通过 Vue 的组件系统实现复用,将 <transition> 或者 <transition-group> 作为根组件,然后将任何子组件放置在其中即可,示例如下:

    Vue.component('my-special-transition', { 
        template: '\ 
            <transition\ 
                name="very-special-transition"\ 
                mode="out-in"\ 
                v-on:before-enter="beforeEnter"\ 
                v-on:after-enter="afterEnter"\ 
            >\ 
                <slot></slot>\ 
            </transition>\ 
        ', 
        methods: { 
            beforeEnter: function (el) { 
                // ... 
            }, 
            afterEnter: function (el) { 
                // ... 
            } 
        } 
    })
    
  • 动态过渡知识点

    所有过渡属性都可以动态绑定,还可以通过事件钩子获取上下文中的所有数据,因为事件钩子都是方法,会根据组件的状态不同,JavaScript 过渡也会有不同的表现

状态过渡

  • 状态动画与侦听器知识点

    可以通过侦听器来监听任何数值 property 的数值更新,并设置动画,当数值更新时,就会触发动画。 总结而言就是通过 watch 来监听数据并调用动画