zoukankan      html  css  js  c++  java
  • 过渡、动画

    transition

    • <transition> 和 <keep-alive> 两个结合一起用,要确保在内层使用 <keep-alive>
    • 所有过渡特性都可以动态绑定,但我们不仅仅只有特性可以利用,还可以通过事件钩子获取上下文中的所有数据,因为事件钩子都是方法。这意味着,根据组件的状态不同,你的 JavaScript 过渡会有不同的表现。
    • 过渡模式:进入和离开同时发生是默认行为。in-out:新元素先进行过渡,完成之后当前元素过渡离开。out-in:当前元素先进行过渡,完成之后新元素过渡进入。
    <transition name="fade" mode="out-in">
      <!-- ... the buttons ... -->
    </transition>
    
    • 使用is绑定变量的组件切换时会触发transition动画
    <transition name="component-fade" mode="out-in">
      <component v-bind:is="view"></component>
    </transition>
    
    new Vue({
      el: '#transition-components-demo',
      data: {
        view: 'v-a'
      },
      components: {
        'v-a': {
          template: '<div>Component A</div>'
        },
        'v-b': {
          template: '<div>Component B</div>'
        }
      }
    })
    
    .component-fade-enter-active, .component-fade-leave-active {
      transition: opacity .3s ease;
    }
    .component-fade-enter, .component-fade-leave-to
    /* .component-fade-leave-active for below version 2.1.8 */ {
      opacity: 0;
    }
    
    • 当有相同标签名的元素切换时,Vue 为了效率只会替换相同标签内部的内容。这样即使该元素包裹在transition中也不会触发动画机制,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们。当key值改变时,transition就认为包裹的元素被改变需要触发动画机制。
    <transition>
      <button v-bind:key="isEditing">
        {{ isEditing ? 'Save' : 'Edit' }}
      </button>
    </transition>
    
    • 给任何元素和组件添加进入/离开过渡,当插入或删除包含在 transition 组件中的元素时,先检测是否应用了 CSS 过渡或动画,再检查是否提供了 JavaScript 钩子函数
    <div id="demo">
      <button v-on:click="show = !show">
        Toggle
      </button>
      <transition name="fade">
        <p v-if="show">hello</p>
      </transition>
    </div>
    
    new Vue({
      el: '#demo',
      data: {
        show: true
      }
    })
    
    .fade-enter-active, .fade-leave-active {
      transition: opacity .5s;
    }
    .fade-enter, .fade-leave-to{
      opacity: 0;
    }
    
    • css过渡动画类

      • v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。(插入后opacity为1,这时存在过渡时间,所以有动画效果。总结,从v-enter类的样式过渡到v-enter-to的样式,如果没又v-enter实际上是过渡到插入元素自身的样式)CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。
      • v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
      • v-enter-to: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
      • v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
      • v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
      • v-leave-to: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
    • 如果你使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。

    • 可以通过以下特性来自定义过渡类名,这个自定义的类名(可以多个)将直接依据规则添加到元素上(动画的使用方法)

    // enter-class
    // enter-active-class    运行时的类
    // enter-to-class (2.1.8+)
    // leave-class
    // leave-active-class
    // leave-to-class (2.1.8+)
    
    <link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
    // webpack使用
    // cnpm i animate.css --save
    // import 'animate.css'
    
    <div id="example-3">
      <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>
    
    • Vue 为了知道过渡的完成,设置了相应的事件监听器 transitionend 或 animationend。当给同一个元素同时设置两种过渡动效,比如 animation 很快的被触发并完成了,而 transition 效果还没结束。在这种情况中,你就需要使用 type 特性并设置 animation 或 transition 来明确声明你需要 Vue 监听的类型。默认 Vue 会等待其在过渡效果的根元素的第一个 transitionend 或 animationend 事件。
    <transition
        name="custom-classes-transition"
        enter-active-class="animated tada"
        leave-active-class="animated bounceOutRight"
        type="transition" // animation
    >
        <p v-if="show">hello</p>
    </transition>
    
    • 可以用 <transition> 组件上的 duration 属性定制一个显性的过渡持续时间 (以毫秒计):动画执行时间依然受过渡和动画CSS控制,但是-to类的添加和元素的删除受这个时间限定
    <transition :duration="1000">...</transition>
    
    // 你也可以定制进入和移出的持续时间:
    <transition :duration="{ enter: 500, leave: 800 }">...</transition>
    
    • 可以在属性中声明 JavaScript 钩子
    <transition
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:after-enter="afterEnter"
      v-on:enter-cancelled="enterCancelled"
    
      v-on:before-leave="beforeLeave"
      v-on:leave="leave"
      v-on:after-leave="afterLeave"
      v-on:leave-cancelled="leaveCancelled"
    >
      <!-- ... -->
    </transition>
    
    // ...
    methods: {
      // --------
      // 进入中
      // --------
    
      beforeEnter: function (el) {
        // ...
      },
      // 当与 CSS 结合使用时
      // 回调函数 done 是可选的
      enter: function (el, done) {
        // ...
        done() // 当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
      },
      afterEnter: function (el) {
        // ...
      },
      enterCancelled: function (el) {
        // ...
      },
    
      // --------
      // 离开时
      // --------
    
      beforeLeave: function (el) {
        // ...
      },
      // 当与 CSS 结合使用时
      // 回调函数 done 是可选的
      leave: function (el, done) {
        // ...
        done()
      },
      afterLeave: function (el) {
        // ...
      },
      // leaveCancelled 只用于 v-show 中
      leaveCancelled: function (el) {
        // ...
      }
    }
    
    new Vue({
      el: '#example-4',
      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.js动画库提供
          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 })
        }
      }
    })
    
    • 推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
    <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>
    
    • 可以通过 appear 特性设置节点在初始渲染的过渡
    <transition appear>
      <!-- ... -->
    </transition>
    
    <transition
      appear
      appear-class="custom-appear-class"
      appear-to-class="custom-appear-to-class" (2.1.8+)
      appear-active-class="custom-appear-active-class"
    >
      <!-- ... -->
    </transition>
    
    <transition
      appear
      v-on:before-appear="customBeforeAppearHook"
      v-on:appear="customAppearHook"
      v-on:after-appear="customAfterAppearHook"
      v-on:appear-cancelled="customAppearCancelledHook"
    >
      <!-- ... -->
    </transition>
    

    transition-group

    • 不同于 <transition>,它会以一个真实元素呈现:默认为一个 <span>。你也可以通过 tag 特性更换为其他元素。
    • 过渡模式不可用
    • 内部元素 总是需要 提供唯一的 key 属性值
    • 内部子元素添加或删除时添加对应的类或者执行对应的函数
    <div id="list-demo" class="demo">
      <button v-on:click="add">Add</button>
      <button v-on:click="remove">Remove</button>
      <transition-group name="list" tag="p">
        <span v-for="item in items" v-bind:key="item" class="list-item">
          {{ item }}
        </span>
      </transition-group>
    </div>
    
    .list-enter-active, .list-leave-active {
      transition: all 1s;
    }
    .list-enter, .list-leave-to
    /* .list-leave-active 只能用于 2.1.8 之后的版本 */ {
      opacity: 0;
      transform: translateY(30px);
    }
    
    • 特别的是他拥有v-move 特性,它会在元素的改变定位的过程中应用(v-move并不是一个vue指令,不需要明写入代码)(使用FLIP 技术 :计算元素的初始位置和最终位置,通过2D/3D转变执行动画,所以改变的是定位。实际是渲染位置的改变,触发了FLIP的使用,导致了定位的改变,添加v-move class)
    • 像之前的类名一样,可以通过 name 属性来自定义前缀,也可以通过 move-class 属性手动设置
    • 元素渲染位置发生改变就会被添加对应的move的class,比如在-leave-active设置被移除的元素position: absolute;那么之后的元素都会因为位置发生改变被添加move的class(被移除的这个元素position改变为absolute,却没有动画效果,是因为当正常流的元素设置position: absolute却没有设置left等位置值时,它的渲染位置是不会发生改变的);
    • 添加元素时也一样,元素先添加,然后通过添加类显示动画;
    • 删除时先添加类显示动画,最后删除。
    • 需要注意的是使用 FLIP 过渡的元素不能设置为 display: inline 。作为替代方案,可以设置为 display: inline-block 或者放置于 flex 中
    • 根据key判断是否同一个元素,从而判断它的渲染位置是否改变
    <div id="flip-list-demo" class="demo">
      <button v-on:click="shuffle">Shuffle</button>
      <transition-group name="flip-list" tag="ul">
        <li v-for="item in items" v-bind:key="item">
          {{ item }}
        </li>
      </transition-group>
    </div>
    
    new Vue({
      el: '#flip-list-demo',
      data: {
        items: [1,2,3,4,5,6,7,8,9]
      },
      methods: {
        shuffle: function () {
          this.items = _.shuffle(this.items)
        }
      }
    })
    
    .flip-list-move {
      transition: transform 1s; // 过渡了2D/3D转变属性
    }
    
  • 相关阅读:
    写页面得来的体会
    C#&java重学笔记(面向对象)
    C#&java重学笔记(函数)
    C#&java重学笔记(变量与操作符)
    深入JS第一天:原型和它的小伙伴们(一)
    兼容性积累
    再深入一点ajax
    Android之内存泄漏调试学习与总结
    优雅地实现Android主流图片加载框架封装,可无侵入切换框架
    优雅地实现Android主流图片加载框架封装,可无侵入切换框架
  • 原文地址:https://www.cnblogs.com/qq3279338858/p/10282080.html
Copyright © 2011-2022 走看看