最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue中transition过渡组件全掌握

    正文概述 掘金(有刃有鱼阮小六)   2021-01-19   866

    Vue中transition过渡组件全掌握

    在冷冰冰的网页上,加上些许过渡或动画,其变化虽小,却能极大的提升页面质感,给人一种顺畅、丝滑的视觉体验。它的实现过程主要是通过css中的transitionanimation来实现的。

    而在vue框架中也对此进行了封装,提供了便捷的过渡用法。

    1、transition组件用法

    在业务开发过程中,最常用的还是transition组件的用法:

    <transition name="slide-fade">
      <p v-if="show"> hello world </p>
    </transition>
    
    /* 可以设置不同的进入和离开动画 */
    /* 设置持续时间和动画函数 */
    .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;
    }
    

    在进入/离开的过渡中,主要有 6 个 钩子被触发,并对应6个class 切换。

    Vue中transition过渡组件全掌握

    如果你的transition组件没有设置name属性,则 v- 是这些类名的默认前缀。如果你使用了<transition name="my-transition"> ,那么 v-enter 会替换为 my-transition-enter

    这6种class类名可以自定义,他们的优先级高于普通的类名:

    <transition name="slide-fade" 
                enter-active-class="custom-enter-active-class"
                leave-active-class="custom-leave-active-class">
      <p v-if="show"> hello world </p>
    </transition>
    
    /* css部分 */
    .custom-enter-active-class {
      animation: bounce-in .5s;
    }
    .custom-leave-active-class {
      animation: bounce-in .5s reverse;
    }
    @keyframes bounce-in {
      0% {
        transform: scale(0);
      }
      50% {
        transform: scale(1.5);
      }
      100% {
        transform: scale(1);
      }
    }
    

    另外在不同组件中切换过渡:

    <transition name="component-fade" mode="out-in">
      <component :is="view"></component>
    </transition>
    
    export default {
      data () {
        return {
        	view: 'v-a'
      	}
      },
      components: {
        'v-a': {
          template: '<div>Component A</div>'
        },
        'v-b': {
          template: '<div>Component B</div>'
        }
      }
    }
    

    默认情况下,上述两个组件的进入和离开是同时发生的,一个离开过渡的时候另一个开始进入过渡,只有离开的组件完成动画之后,才会把位置让出来,通常这会造成一种卡顿的效果(如果两个元素都设置了绝对定位,则没有这个问题)。

    可以通过添加过渡模式mode来满足我们的需求:

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

    通常我们更多的会使用out-in,让当前元素先离开,然后再进行新元素的进入。

    <transition name="fade" mode="out-in">
      <!-- 不同元素 -->
    </transition>
    

    了解了以上的用法,基本就可以实现大部分业务场景了。

    2、使用JavaScript动态过渡

    在大部分场景下,我们主要是使用css来进行过渡,css已经前置写好了,但在某些情况下,我们还需要动态过渡。

    动态过渡最基本的操作就是绑定动态属性,比如name,当有不同的情况时切换不同的过渡效果。

    <transition :name="transitionName">
      <!-- ... -->
    </transition>
    

    不过这同样需要我们提前写好对应的过渡效果,除此之外,最直接的实现动态过渡的方式是使用JavaScript过渡:

    <transition
      @before-enter="beforeEnter"
      @enter="enter"
      @after-enter="afterEnter"
      @enter-cancelled="enterCancelled"
    
      @before-leave="beforeLeave"
      @leave="leave"
      @after-leave="afterLeave"
      @leave-cancelled="leaveCancelled"
    >
      <!-- ... -->
    </transition>
    
    methods: {
      // 过渡进入之前触发
      beforeEnter: function (el) { },
      // 过渡进入时触发
      enter: function (el, done) {
        // ...
        // 当与 CSS 结合使用时,回调函数 done 是可选的
        // 不用CSS过渡,设置了:css="false",则必须使用回调done 
        done()
      },
      // 过渡进入结束时触发
      afterEnter: function (el) { },
      // 过渡进入被取消时触发
      enterCancelled: function (el) { },
    	// 在离开之前触发
      beforeLeave: function (el) { },
      // 离开时触发
      leave: function (el, done) {
        // ...
        // 当与 CSS 结合使用,回调函数 done 是可选的
        // 不用CSS过渡,设置了:css="false",则必须使用回调done 
        done()
      },
      // 离开后触发
      afterLeave: function (el) { },
      // 离开过程被取消时触发(只用于 v-show 中)
      leaveCancelled: function (el) { }
    }
    

    上面这些JavaScript过渡钩子可以和 CSS transitions/animations 同时使用,也可以单独使用。

    不过既然你都使用了 JavaScript 过渡,那么推荐就不用CSS过渡,元素添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响

    如这个例子:

    <!-- Velocity 和 jQuery.animate 的工作方式类似,也是用来实现 JavaScript 动画的一个很棒的选择 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
    
    <div id="example-4">
      <button @click="show = !show">
        Toggle
      </button>
      <transition
        @before-enter="beforeEnter"
        @enter="enter"
        @leave="leave"
        :css="false"
      >
        <p v-if="show">
          Demo
        </p>
      </transition>
    </div>
    
    new Vue({
      el: '#example-4',
      data: {
        show: false
      },
      methods: {
        // 钩子函数里写具体的过渡数据,可以实现js动态控制
        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 })
        }
      }
    })
    

    3、初始渲染appear

    上述过渡的用法通常需要元素或者组件有变化才会触发,如需要v-ifv-show动态组件等。

    如果你的需求是第一次进页面的时候,它就过渡渲染出来,之后是不需要再过渡的,那可以使用appear这个属性。如下面这个示例:

    Vue中transition过渡组件全掌握

    <!-- appear 也可以自定义 CSS 类名 --> 
    <transition appear
                appear-class="custom-appear-class"
                appear-active-class="custom-appear-active-class"
                appear-to-class="custom-appear-to-class">
      <p>我是一段测试appear初始渲染文字</p>
    </transition>
    
    .custom-appear-class{
      opacity: 0;
    }
    .custom-appear-active-class{
      transition: all 3s;
    }
    .custom-appear-to-class{
      opacity: 1;
    }
    

    appearenter有点像,但它只在初始渲染的时候触发,并且只要把触发之前和触发之后的状态设置不同,便可以实现中间的自然过渡。

    同时,它也可以用JavaScript钩子函数实现:

    <transition appear 
                @before-appear="customBeforeAppearHook"
                @appear="customAppearHook"
                @after-appear="customAfterAppearHook"
                @appear-cancelled="customAppearCancelledHook">
      <!-- ... -->
    </transition>
    

    4、列表过渡和v-move

    同一时间内渲染单个节点,或者多个节点中的一个,使用<transition>组件,如果同时渲染多个节点,比如整个列表,则需要用<transition-group>组件,该组件有几个特点:

    • 不同于 <transition>,它会以一个真实元素呈现:默认为一个 <span>。可以通过 tag 属性更换为其他元素。
    • 列表渲染中没有过渡模式。
    • 内部元素必须要提供key值。
    <!-- 设置tag属性为p元素,v-for中的每一项设置key值 -->
    <!-- items为一个连续数字组成的数组 [0, 1, 2, ...] -->
    <transition-group name="list" tag="p" class="list-item">
       <span v-for="item in items" :key="item">
         {{ item }}
       </span>
    </transition-group>
    
    .list-item {
      display: inline-block;
      margin-right: 10px;
    }
    .list-enter-active, .list-leave-active {
      transition: all 1s;
    }
    .list-enter, .list-leave-to {
      opacity: 0;
      transform: translateY(30px);
    }
    

    Vue中transition过渡组件全掌握

    效果如上,但是这有一个问题:当添加和移除元素的时候,周围的元素会瞬间移动到他们的新布局的位置,有一种卡顿的感觉。

    要解决这个问题可以通过<transition-group>组件中的 v-move class,它会在元素的改变定位的过程中应用。像之前的类名一样,可以通过 name attribute 来自定义前缀,也可以通过 move-class attribute 手动设置。

    于是只要在上面的例子中修改一下css:

    .list-item {
      display: inline-block;
      margin-right: 10px;
    }
    /* 这里增加和一个.list-move类样式,它会在元素改变的过程中生效 */
    .list-move{
      transition: all 1s;
    }
    .list-enter-active, .list-leave-active {
      transition: all 1s;
    }
    /* 这里在元素离开时增加一个绝对定位属性 */
    /* 这样元素离开的瞬间就会触发改变位置,使上面的.list-move生效 */
    /* 如果不加绝对定位,则元素离开动作完成后周围的元素才会移动到它的位置 */
    /* 而那个时候所有过渡已结束 .list-move已经被移除,会造成卡顿感觉 */
    .list-leave-active {
      position: absolute;
    }
    .list-enter, .list-leave-to {
      opacity: 0;
      transform: translateY(30px);
    }
    

    Vue中transition过渡组件全掌握

    如此就有了一种丝滑的感觉,另外上述css可进一步修改简化:

    /* 直接在元素上增加transition属性 */
    /* 它会在元素改变的所有过程中生效,包括v-move的时候 */
    .list-item {
      display: inline-block;
      margin-right: 10px;
      transition: all 1s;
    }
    /* 因此v-move和v-active相关的均可不需要了 */
    /* 只要在元素离开时增加一个绝对定位属性即可 */
    .list-leave-active {
      position: absolute;
    }
    .list-enter, .list-leave-to {
      opacity: 0;
      transform: translateY(30px);
    }
    

    起源地下载网 » Vue中transition过渡组件全掌握

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元