Vue 2.0学习笔记:Vue的transition

栏目: 编程语言 · 发布时间: 5年前

内容简介:动效在Web中一直是一个有争议的问题。动效做得好有助于在你的Web程序上锦上添花,甚至是留住你的用户,也可以具有较好的用户体验;反之,如果动效运用的不好,会给用户带来一种反感,让用户迅速地离开你的应用。怎么提供更友好的动效,并不是今天我们要讨论的重点,我们要讨论的是:在本文中,我们将先重点了解Vue中处理CSS的在具体了解Vue中的

动效在Web中一直是一个有争议的问题。动效做得好有助于在你的Web程序上锦上添花,甚至是留住你的用户,也可以具有较好的用户体验;反之,如果动效运用的不好,会给用户带来一种反感,让用户迅速地离开你的应用。怎么提供更友好的动效,并不是今天我们要讨论的重点,我们要讨论的是: 在Vue应用程序中如何添加动效? 在Vue中,提供了多种方法来给你的运用程序添加动效,比如CSS的 transitionanimation 动效,以及在Vue的生命周期的钩子函数中操作DOM。甚至你还要以使用第三方动画库,比如 GSAPVelocity.js 来制作动效。

在本文中,我们将先重点了解Vue中处理CSS的 transition 的原理。有了这些知识,就可以开始创建自己的过渡动效。一旦掌握了这些基础知识,就可以快速掌握Vue中的 transitionanimation 的全部功能。

transition vs animation

在具体了解Vue中的 transition 之前,咱们先简单的了来了解一下 transitionanimation 之间的差异(这里所指的是CSS中两者的差异)。先上一张录制的动图:

Vue 2.0学习笔记:Vue的transition

两者的效果就如下图所示这样:

Vue 2.0学习笔记:Vue的transition

如果用代码来描述的话:

/* transition*/
.button {
    background: blue;
    transition: background;

    &:hover {
        background: red;
    }
}

/* animation */
@keyframe spin {
    0% {
        color: red;
    }
    50% {
        color: blue;
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

.element {
    animation: spin 1s ease-in-out 2s infinite;
}

也就是说, transition 是指一个元素从 状态 A 状态B ,即开始状态是 A ,结束状态是 B 。而其主要的目的是创建一个自然的演示,告诉用户的交互行为已经发生了更改(就是从 A 变成了 B )。在现实的Web应用中这样的示例也非常的多。比如下拉菜单的效果就是其中的一个典型案例。默认情况下,下拉菜单是收缩闭合的(隐藏不见,就是我们所说的状态 A ),当用户点击了或者鼠标悬浮在菜单项上,下拉菜单就会展开(下拉菜单可见,就是我们所说的状态 B )。这样的一个过程如果添加了 transition 的话,就自钱的完成了闭合(隐藏)自动过渡到展开(可见)状态。比如下图所示:

Vue 2.0学习笔记:Vue的transition

animationtransition 有很大的不同之处,从状态 A 到状态 B 之间有很多中间态,而这些被称为 关键帧 。因此, animation 也常常被称为 帧动画 ,也有人称为 补间动画 。比如下图所示:

Vue 2.0学习笔记:Vue的transition

从上图我们也可以看出来, animation 有很多中间态,即,可以从 AB ,再到 C ,再到 D ,甚至更多。其主要目的是 不断展示某些东西正在改变 。它们可以有结束状态,但与 transition 不同,它们不限于两种状态。比如下面这样的一个示例,它不断地从一种状态变化到另一种状态,但它最终可能会结束。

Vue 2.0学习笔记:Vue的transition

在某种程度上, animation 只是 transition 的一个超级集合,因为它添加了更多的中间状态。虽然 transition 只是从状态 A 到状态 B,但 animation 可以根据需要拥有任意多的中间状态。也就是说,只要理解了 transition 的基本原理之后,在去理解 animation 就不是什么一件难事了。这也就是我们今天为什么把重点放在 transition`上。

transition元素

在Vue中有一个 <transition> 元素(即一个容器),它主要用来处理元素或组件上的 transition 动效,CSS和JavaScript的 animation 动效,而且会让你处理这些动效变得简地多。而在CSS的 transition 动效中, <transition> 元素主要负责应用和取消类(元素的类名)。而你所要做的就是定义元素在 transition 动效期间元素的样式。

<transition> 在Vue中使用非常的简单,把要带动效的元素放到这个容器之中,同时使用 name 给其一个名称,比如 fade

<transition name="fade">
    <h1 v-if="show">Hello! W3cplus.com (^_^)</h1>
</transtion>

当在 <transition> 容器中的元素在显示(插入)或隐藏(删除)时,Vue会自动嗅探到目标元素是否应用了CSS的 transitionanimation ,如果是,在恰当的时机添加或删除CSS类名。

简单地说:

<transition> 是Vue已经封装好的一个组件,可以给任何元素和组件添加进入或离开过渡效果。

在Vue中的下面这几种情形会产生相应的过渡或动画效果:

v-if
v-show

比如下面这个示例:

<!-- FadeText -->
<template>
    <div class="wrapper">
        <transition name="fade">
            <h1 v-if="isShow">{{ msg }}</h1>
        </transition>
        <button @click="isToggle" :class="isShow ? 'is-show' : 'is-hidden'">
            {{ isShow ? "隐藏" : "显示" }}
        </button>
    </div>
</template>

<script>
export default {
    name: "FadeText",
    data() {
        return {
            isShow: true,
            msg: "Hello! W3cplus.com (^_^)"
        };
    },
    methods: {
        isToggle() {
            this.isShow = !this.isShow;
        }
    }
};
</script>

<style scoped>
    .fade-enter-active,
    .fade-leave-active {
        transition: opacity 0.5s;
    }
    .fade-enter,
    .fade-leave-to {
        opacity: 0;
    }
</style>

效果如下:

上面这个简单的过渡效果使用的是CSS的 transition 方式来实现。那么 v-if 在切换元素 h1 的时候发生了什么呢?

  • v-if 绑定的值 isShowtruefalse 之间切换的时候, <transition> 中的元素 <h1> 会插入和删除之间进行切换
  • 自动嗅探目标元素 h1 是否应用了CSS的 transitionanimation 。如果是,则会在元素插入时添加CSS类名,并判断动画加载完之后删除CSS类名
  • 如果过渡组件提供了 JavaScript钩子函数 (这部分后面会介绍),这些钩子函数在恰当的时机被调用。在这个示例中并没有用到JavaScript钩子函数,所以不会被执行
  • 如果没有找到JavaScript钩子并且也没有检测到CSS的 transitionanimation ,DOM操作(插入或删除)在下帧中立即执行。( 注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同 )

这个时候,通过浏览器的动画( Animations )选项可以看到动效的整个过程,如下图所示:

Vue 2.0学习笔记:Vue的transition

过渡的类名

在Vue中使用 <transition> 制作过渡效果时,可以给过渡元素添加类名,在Vue中有六个类名,可以使用它们分别处理处理元素插入和删除时过渡效果。其中三个类用于处理元素插入时状态 A 到状态 B 过渡,另外三个类用于处理元素删除时状态 A 到状态 B 的过渡。

在插入或显示组件时发生 enter 过渡,对应的类名是 v-enterv-enter-activev-enter-to ;在隐藏或删除组件时发生 leave 过渡,对应的类名是 v-leavev-leave-activev-leave-to 。每个类对应的作用如下:

  • v-enter :定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  • v-enter-active :定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  • v-enter-to : 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
  • v-leave : 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  • v-leave-active :定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  • v-leave-to : 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

用下图来阐述将会更清晰一些:

Vue 2.0学习笔记:Vue的transition

对于这些在过渡中切换的类名来说,如果你使用一个没有使用 name<transition> ,则 v- 是这些类名的默认前缀。如果你使用了 <transition name="fade"> ,那么 v-enter 会替换为 fade-enter ,其他类名也是如此。另外, v-enter-activev-leave-active 可以控制进入/离开过渡的不同的缓和曲线,有关于这部分将在后面会介绍。

结合起来,我们可以用一张图来表示Vue中过渡动效的生命周期,即动效开始、过程、结束对应的类的变化:

Vue 2.0学习笔记:Vue的transition

回到上面的示例中来,在元素 h1 加载到DOM之前, h1 会添加 fade-enter 类名,对应的动效也就被添加到该元素中,只对应一帧。因此,在DOM渲染时,将动画的 opacity:0 应用到 h1 元素上,此时该元素也就隐藏不可见。在动效的整个过程中, fade-enter-active 类也被添加到该元素中,在该示例中,动画被设置为 .5sfade-leavefade-leave-active 也以相同的方式运用于 h1 元素上。

在示例中,并没有显式的在 fade-leave 类中设置 opacity: 1 ,那是因为 opacity 的默认值已经是 1 。这也就是为什么在 fade-enter-active 结束时 opacity 也不显式设置为 1 的原因。

在Vue中,如果元素放置到 <transition> 中,Vue会自动检测元素上的 v-if 指令。比如上面的示例,如果 isShow 的值为 true ,那么 h1 会渲染显示,当你点击按钮时,会自动切换 isShow 的值。从而也控制了 h1 元素的显示或隐藏(插入或删除)。

这里需要注意的一点是, Vue只能对 <transition> 中的一个元素进行动效处理。相反,在任何给定的实例中,只能将 <transition> 中的一个元素插入到DOM中 。比如下同这个示例,在Vue中无法正常的工作:

<!-- ToggleAlert.vue -->
<template>
    <div class="toogle-alert">
        <button @click="isToggle" :class="isShow ? 'is-show' : 'is-hidden'">
        {{ isShow ? "隐藏" : "显示" }}
        </button>

        <transition name="fade">
            <div class="alert alert-info" v-if="isShow" key="info">{{ alertInfoMsg }}</div>
            <div class="alert alert-error" v-if="isShow" key="error">{{ alertErrorMsg }}</div>
        </transition>
    </div>
</template>

<script>
export default {
    name: "ToggleAlert",
    data() {
        return {
            isShow: true,
            alertInfoMsg: "Hello! W3cplus.com!",
            alertErrorMsg: "Goodbye! W3cplus.com!"
        };
    },
    methods: {
        isToggle() {
            this.isShow = !this.isShow;
        }
    }
};
</script>

<style scoped>
.fade-enter,
.fade-leave-to {
    opacity: 0;
}
.fade-enter-active,
.fade-leave-activ {
    transition: opacity 0.5s cubic-bezier(1, 0.5, 0.8, 1);
}
</style>

这个时候浏览器会报错:

Vue 2.0学习笔记:Vue的transition

如果我们把另一个 divv-ifv-else 来替代:

在Vue中 <transition> 中有多个元素需要有动效效果时,需要使用 <transition-group> 来替代,不然在Vue中则会报错。有关于 <transition-group> 更详细的介绍,我们后续会单独花时间来阐述。另外,在 <transition> 中有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。即使在技术上没有必要,给在 <transition> 组件中的多个元素设置 key 是一个更好的实践。

现在,你看到的效果可以没有你想像的那么顺滑。这主要是因为,Vue在将第二个元素插入到DOM之前,并不会等第一个元素从DOM中完全删除。所以你看到效果就如上例所示,两个元素之间动效的切换似乎有点闪跳一样。不过我们可以通过 transition 的过渡模式来处理。

过渡模式

上面的示例存在一个问题,先看下图这个效果:

Vue 2.0学习笔记:Vue的transition

div.alert-infodiv.alert-error 两个元素都被重绘了,一个离开过渡的时候另一个开始进入过渡。其实这也是 <transition> 的默认行为,即 进入和离开同时发生

在Vue中提供了两种过渡模式来解决上述问题:

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

这样我们就可以使用 out-in 重写上面的示例:

<transition name="fade" mode="out-in">
    <div class="alert alert-info" v-if="isShow" key="info">
        {{ alertInfoMsg }}
    </div>
    <div class="alert alert-error" v-else="!isShow" key="error">
        {{ alertErrorMsg }}
    </div>
</transition>

效果如下:

设置初始渲染的过渡

在Vue中,可以通过 appear 特性设置节点在初始渲染的过渡。

<transition name="fade" mode="out-in" appear>
    <div class="alert alert-info" v-if="isShow" key="info">
        {{ alertInfoMsg }}
    </div>
    <div class="alert alert-error" v-else="!isShow" key="error">
        {{ alertErrorMsg }}
    </div>
</transition>

这里默认和进入和离开过渡一样,同样也可以自定义 CSS 类名:

<transition
appear
appear-class="custom-appear-class"
appear-to-class="custom-appear-to-class" 
appear-active-class="custom-appear-active-class"
>
    <!-- ... -->
</transition>

同样可以对应的类名添加样式:

.custom-appear-class {
    opacity: 0;
    transform: translateX(100%);
}
.custom-appear-active-class {
    transition: 2s;
}

比如上面的示例,按照上面的代码进行调整之后,可以发看到第一个 .alert 插入到DOM中时,整个 .alert 会从右侧移入进来,效果如下:

示例: 使用transition制作一个圆形菜单

通过上面的学习,我们接下来使用Vue的 transition 来实现下面这样的一个圆形菜单效果:

Vue 2.0学习笔记:Vue的transition

这个案例其实非常的简单,通过一个 <transition> 来触发多个子元素的过渡效果,我们只需要定义元素对应的过渡效果即可,而其他的事情都将交给Vue来搞定。

<transition name="move" mode="out-in" appear>
    <ul class="menu" v-show="isShow">
        <li
        v-for="(item, index) in menus"
        :key="index"
        class="menuitem-wrapper"
        >
            <div class="icon-holder">
                <a href="#" class="menu-item">
                    <i class="material-icons">{{ item }}</i>
                </a>
            </div>
        </li>
    </ul>
</transition>

只需要在对应的 transition 类中控制 transform 的样式:

.move-enter-active,
.move-leave-active {
    transition: all 0.08s ease-in-out;
}

.move-enter,
.move-leave-to {
    transform: scale(0);
}

最终效果如下:

总结

这篇文章主要介绍了Vue中如何使用 <transition> 来实现 transition 动效。这只是Vue中制作动效的最基础部分,但这些基础部分是帮助我们实现更为复杂的动效的基础。在接下来中我们将再一起探讨如何在Vue中实现CSS的 animation 效果,以入如何和第三方库一起结合实现动效。如果感兴趣的话,欢迎持续关注后续的相关更新。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

REST实战

REST实战

Jim Webber、Savas Parastatidis、Ian Robinson / 李锟、俞黎敏、马钧、崔毅 / 东南大学出版社 / 2011-10 / 78.00元

为何典型的企业项目无法像你为web所开发的项目那样运行得如此平滑?对于建造分布式和企业级的应用来说,rest架构风格真的提供了一个可行的替代选择吗? 在这本富有洞察力的书中,三位soa专家对于rest进行了讲求实际的解释,并且通过将web的指导原理应用到普通的企业计算问题中,向你展示了如何开发简单的、优雅的分布式超媒体系统。你将会学习到很多技术,并且随着一家典型的公司从最初的小企业逐渐成长为......一起来看看 《REST实战》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具