vue2.0 transition -- demo实践填坑
前言
vue1.0版本和2.0版本的过渡系统改变还是蛮彻底的,具体请自行详看文档介绍:https://vuefe.cn/v2/guide/migration.html#过渡。在使用2.0版本做过渡效果的时候,虽然比1.0版本强大很多,但是实践过程中还是踩了一些不应该踩但是还是踩了的坑。虽然官网文档已经很详细地介绍了各种应用场景,但是这里还是通过几个小demo案例来感受下vue2.0 transition 带来的便利吧!
实践
这里将通过四个实践小案例来体验和学习css过渡,css动画,javascript钩子,列表过渡的应用。至于案例用到的知识点就请自行学习官网文档。
css过渡--实践
先来看看demo效果:

这个案例其实很简单,通过一个transition来触发多个子元素的过渡效果,我们只需要定义元素对应的过渡效果就可以,其他事情vue会帮我们搞定,由此可以扩展出其他酷炫的过渡场景效果。先来看看这个简单案例的代码实现:
<template>
<div class="app">
<button @click="showMenu" class="btn">{{text}}</button>
<transition name="move">
<div class="menu" v-show="show">
<div class="inner inner-1">1</div>
<div class="inner inner-2">2</div>
<div class="inner inner-3">3</div>
</div>
</transition>
</div>
</template>
<script type="text/ecmascript-6">
export default {
data () {
return {
show: false
};
},
methods: {
showMenu () {
this.show = !this.show;
}
},
computed: {
text () {
return this.show ? '收' : '开';
}
}
};
</script>
<style lang="stylus" rel="stylesheet/stylus">
.app
.btn
position: fixed
bottom: 50px
right: 10px
z-index: 10
width: 50px
height: 50px
line-height: 50px
border-radius: 50%
border: none
outline: none
color: #fff
font-size: 18px
background: blue
.menu
position: fixed
bottom: 50px
right: 10px
width: 50px
height: 50px
border-radius: 50%
transition: all .7s ease-in
&.move-enter-active
.inner
transform: translate3d(0, 0, 0)
transition-timing-function: cubic-bezier(0, .57, .44, 1.97)
.inner-1
transition-delay: .1s
.inner-2
transition-delay: .2s
.inner-3
transition-delay: .3s
&.move-enter, &.move-leave-active
.inner
transition-timing-function: ease-in-out
.inner-1
transform: translate3d(0, 60px, 0)
transition-delay: .3s
.inner-2
transform: translate3d(40px, 40px, 0)
transition-delay: .2s
.inner-3
transform: translate3d(60px, 0, 0)
transition-delay: .1s
.inner
display: inline-block
position: absolute
width: 30px
height: 30px
line-height: 30px
border-radius: 50%
background: red
text-align: center
color: #fff
transition: all .4s
.inner-1
top: -50px
left: 10px
.inner-2
left: -30px
top: -30px
.inner-3
left: -50px
top: 10px
</style>
可以看到我们的代码基本主要是完成css过渡效果的样式,而触发过渡效果只是简单地通过一个click事件就搞定了,vue会自动嗅探目标元素是否有 CSS 过渡或动画,并在合适时添加/删除 CSS 类名。那下一个demo就来简单实现一下使用css animation 做过渡的效果。
css 动画--实践
先来看看demo效果:

这个案例其实跟上面的demo差不多,不同之处在于过渡效果是使用css动画来实现,看下实现的代码:
<template>
<div class="app">
<button @click="showball" class="btn">show</button>
<transition name="move" type="animation">
<div class="ball" v-show="show">
<div class="inner"></div>
</div>
</transition>
</div>
</template>
<script type="text/ecmascript-6">
export default {
data () {
return {
show: false
};
},
methods: {
showball () {
this.show = !this.show;
}
}
};
</script>
<style lang="stylus" rel="stylesheet/stylus">
@keyframes shape-change {
0%, 100% {
border-radius: 50%
background: red
}
50% {
border-radius: 0
background: blue
}
}
@keyframes moveball-in {
0% {
transform: translate3d(300px,-200px,0)
}
50% {
transform: translate3d(100px,-400px,0)
}
100% {
transform: translate3d(0,0,0)
}
}
@keyframes moveball-out {
0% {
transform: translate3d(0,0,0)
}
50% {
transform: translate3d(100px,-400px,0)
}
100% {
transform: translate3d(300px,-200px,0)
}
}
.app
.btn
width: 40px
height: 30px
margin-top: 40px
border: none
outline: none
background: red
color: #fff
.ball
position: absolute
bottom: 20px
left: 20px
width: 50px
height: 50px
transition: all 1s cubic-bezier(.22,-0.86,.97,.58)
&.move-enter-active
opacity: 1
animation: moveball-in 1s
.inner
animation: shape-change 1s
&.move-leave-active
opacity: 0.8
animation: moveball-out 1s
.inner
animation: shape-change 1s
.inner
display: inline-block
width: 30px
height: 30px
border-radius: 50%
background: red
transition: all 1s linear
</style>
从css代码可以看出,我们只是在vue过渡类名下加了不同的animation而已。官网文档明确说明当只使用transition或animation其中一种时,vue是能自动监听对应的类型的,但是如果同一个元素同时使用两种效果,就需要明确指定监听哪一种类型,不过官网并没有给出具体的栗子。那其实这个demo已经简单地实现同时使用两种类型的情况,可以看到有一个透明度的变化。但是假如animation里使用了transform,并且外面也使用了transform的话,那么元素在过渡的时候动画效果就会有冲突,效果就有点出入了。
JavaScript钩子 -- 实践
前两个栗子都是有进入和离开的过渡,但是如果一些场景只需要进入过渡然后就结束了,那么这时就可以使用JavaScript钩子结合CSS transitions/animations来实现,当然也可以单独使用。看下demo:

这个一个非常low的模拟炮弹发射的场景,可以看到小球有抛物线轨迹运动的过渡,而且发射出去就不会再回来了,那么这个demo就是使用了JavaScript钩子结合css来实现的,接下来看下关键代码:
<template>
<div class="app">
<div class="gun" @click="launch($event)"></div>
<div class="shells-wrapper">
<transition v-for="shell in shells" name="launch-shell" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
<div class="shell" v-show="shell.show">
<div class="inner"></div>
</div>
</transition>
</div>
<div class="goal"></div>
</div>
</template>
首先,由于本身这个demo是一组元素的过渡,所以有些童鞋就会觉得用2.0提供的transition-group不就行了嘛。不过transition-group是列表过渡,我的理解是那一组元素是相关联的、互相影响的,但是这个demo的元素每个都是独立的,只不过是一组独立的元素过渡,所以还是用transition比较合理,那使用v-for就可以实现一组相同过渡的元素啦。接下来看JavaScript钩子怎么实现这个过渡:
export default {
data () {
return {
shells: [
{
show: false
},
{
show: false
},
{
show: false
}
]
};
},
methods: {
launch (event) {
for (let i = 0; i < this.shells.length; i++) {
let shell = this.shells[i];
if (!shell.show) {
shell.show = true;
shell.target = event.target;
return;
}
}
},
beforeEnter (el) {
let count = this.shells.length;
while (count--) {
let shell = this.shells[count];
if (shell.show) {
let rect = shell.target.getBoundingClientRect();
let left = rect.left - 32;
let top = -(window.innerHeight - rect.top - 15);
el.style.display = '';
el.style.webkitTransform = `translate3d(0,${top}px,0)`;
el.style.transform = `translate3d(0,${top}px,0)`;
let inner = el.getElementsByClassName('inner')[0];
inner.style.webkitTransform = `translate3d(${left}px,0,0)`;
inner.style.transform = `translate3d(${left}px,0,0)`;
}
}
},
enter (el, done) {
/* eslint-disable no-unused-vars */
let refresh = el.offsetHeight;
this.$nextTick(() => {
el.style.webkitTransform = 'translate3d(0,0,0)';
el.style.transform = 'translate3d(0,0,0)';
let inner = el.getElementsByClassName('inner')[0];
inner.style.webkitTransform = 'translate3d(0,0,0)';
inner.style.transform = 'translate3d(0,0,0)';
});
done();
},
afterEnter (el) {
let ball = this.shells[0];
ball.show = false;
el.style.display = 'none';
}
}
};
过渡元素就不需要为其添加vue的过渡css类名了,只需在元素本身添加transition即可,那vue在之前css过渡的时候会自动帮我们去添加对应的类名来完成过渡效果,但是用javascript钩子就需要我们自己完成这个始末状态的设置了。当我们点击触发一个过渡的时候,我们在beforeEnter里先拿到当前元素的偏移位置,然后给过渡元素设置其起始位置,在enter里需要重新触发下浏览器的重绘,然后在下一帧重新设置元素的结束位置,这时就会产生过渡效果,在过渡完成后我们将当前元素隐藏即可。那刚才讲到的列表过渡,接下来就是关于使用transition-group的一个小demo了。
transition-group -- 实践
先看下demo效果:

其实就是个简单的todo lists的小demo,可以看到,当其中一个元素过渡的时候,会影响其他元素的过渡。当然,删除按钮其实本身也是一个transition过渡,也就是说可以在transition-group里使用transition,看下相关代码:
<template>
<div class="app">
<button @click="add" class="add-btn">+</button>
<transition-group name="slide" tag="ul" class="list-wrapper">
<li class="list" v-for="(item, index) in lists" v-touch:swipeleft="showBtn.bind(this, index)" v-touch:swiperight="hideBtn.bind(this, index)" :key="item">
<span class="text">{{item.text}}</span>
<transition name="move">
<button class="del-btn" @click="delList(index)" v-show="item.show">删除</button>
</transition>
</li>
</transition-group>
</div>
</template>
有个小坑的地方就是,之前看官网列表过渡的栗子,它是一个数组,元素都是数字,并且每一项都必须设置唯一的key值。所以我完成demo的时候就自作聪明地将索引值传给key,结果过渡老是不对,后来换成对应的item就正常了(生无可恋脸)。这个demo用到了vue-touch,虽然github上说不支持2.0版本了,但是有一个next分支是支持的,只需在项目下安装它即可:
sudo npm install --save git://github.com/vuejs/vue-touch.git#next
这里看下主要的样式:
.list
display: flex
width: 100%
height: 40px
line-height: 40px
margin-bottom: 10px
color: #666
font-size: 14px
background: #eee
transition: all .4s
&.slide-move
transition: transform 1s
&.slide-enter
transform: translate3d(-100%, 0, 0)
&.slide-leave-active
position: absolute
transform: translate3d(-100%, 0, 0)
&:last-child
margin-bottom: 0
.del-btn
flex: 0 0 60px
border: none
outline: none
color: #fff
background: red
transition: all .4s
&.move-enter, &.move-leave-active
transform: translate3d(70px, 0, 0)
.text
flex: 1
padding-left: 20px
如果改变定位过渡的duration与进入离开一样的话,其实可以不用-move,这里设置-move的过渡的duration不同于元素进入离开的duration产生一种速度差,看起来舒服点。而且-leave-active需要设置position: absolute才会有效果。现在看来其实列表过渡也是很容易实现的。
最后
其实vue2.0过渡系统还提供了其他场景的过渡应用,这里就不展开赘述了。引用官网文档的一句话:唯一的限制是你的想象力。哈哈...
PS: 如需转载,请注明出处,谢谢!!!
vue2.0 transition -- demo实践填坑的更多相关文章
- 【重点突破】—— Vue2.0 transition 动画Demo实践填坑
前言:vue1.0版本和2.0版本的过渡系统改变是很大的,具体请详看文档介绍.本文转载自郭锦荣的博客,一共列举了四种transition的使用实践,分别是css过渡.css动画.javascript钩 ...
- Node + Express + vue2.0 + Webpack项目实践
技术 Express.Vue.Vue-Router.Vue-Resource.Webpack Vue vue 的组件化思想和 React 很像,一个 vue 组件将 html.css 和 js 都写在 ...
- Vue2.0 Transition常见用法全解惑
Vue2.0的过渡系统(transition)有了很大的改变,想把1.0的项目迁移到2.0,着实需要费一些功夫,今天我就要把vue2.0的过渡系统的用法搞清楚,因为之前确实踩了不少坑.这里只涉及单元素 ...
- 【数据售卖平台】—— Vue2.0入门学习项目爬坑
前言:这个项目是我从零学习Vue2.0时用于练习基础知识的入门项目,包含了Vue2.0几乎所有项目都会用到的基础功能,是新手用来练手的好项目,这里温故知新对功能点做一个总结.github地址:http ...
- Vue2.0 + Element-UI + WebAPI实践:简易个人记账系统
最近正在学习Vue2.0相关知识,正好近期饿了么桌面端组件Element-UI发布,便动手做了一款简易个人记账系统,以达到实践及巩固目的. 1.开发环境 Win10 + VS2015 + Sqlser ...
- vue2.0 transition 多个元素嵌套使用过渡
在做vue的demo的时候遇到一个问题,多个嵌套的元素如何设置transition? 我的代码:代码中元素整体做平移,里面的inner中做旋转,实现一个圆形滚动的效果 <transition n ...
- vue2.0 keep-alive最佳实践
1.基本用法 vue2.0提供了一个keep-alive组件用来缓存组件,避免多次加载相应的组件,减少性能消耗 <keep-alive> <component> <!-- ...
- vue2.0 transition 手风琴
<div class="food"> <button @click="show=!show">show</button> & ...
- 转:vue2.0 keep-alive最佳实践
转载至:https://segmentfault.com/a/1190000008123035 1.基本用法 vue2.0提供了一个keep-alive组件用来缓存组件,避免多次加载相应的组件,减少性 ...
随机推荐
- Office版本问题0x80029C4A
说来奇怪,以前运行正常的程序(涉及excel表格输出),现在运行失败了,一调试,发现了如下问题: 无法将类型为"Microsoft.Office.Interop.Excel.Applicat ...
- MVC.Net: 解决Attempted to access an unloaded appdomain的问题
在C#中尝试获取AD帐号信息时,会随机出现Attempted to access an unloaded appdomain的问题,解决方法如下: 将 principalContext = new P ...
- Python数据结构与算法--数据类型
从数据类型开始 Python支持面向对象的编程范式,这意味着Python把数据看成解决问题的关键. 在Python中,类似其他的面向对象的编程语言, 我们定义一个类,用来描述数据是什么 (状态) 和数 ...
- iOS单元测试1
iOS单元测试1 iOS单元测试分为两种类型的测试: 应用测试.应用程序测试可以检查app的代码组件,比如计算机的算术运算的例子.你可以利用应用程序测试来确保你的UI空间控件保持原有位置,并且你的控件 ...
- CSS 指定选择器(十一)
一.指定选择器 有时个会希望控制某个元素在一定范围内的对象样式,这时就可以把元素与Class或者Id选择器结合起来使用 <!DOCTYPE html PUBLIC "-//W3C//D ...
- 【原】error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string'
今天遇到一个非常难以排查的BUG,谷歌度娘都问过了依旧无解,最后自己重新尝试之后找到解决方案: 先看一下报错信息: 1>.\lenz.cpp(2197) error C2679: binary ...
- HTML5 拖放
拖放(Drag 和 drop)是 HTML5 标准的组成部分. 拖放 拖放是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖放是标准的一部分,任何元素都能够拖放. 浏览器支持 I ...
- 那些Xcode不能错过的插件
转载来自网络 古人云“工欲善其事必先利其器”,打造一个强大的开发环境,是立即提升自身战斗力的绝佳途径!以下是搜集的一些有力的XCode插件. 1.全能搜索家CodePilot 2.0 你要找的 ...
- 《慕客网:IOS-动画入门》学习笔记
新建Cocoa Touch Class,语言是swift 然后继续为界面添加一个普通的View Controller,并且添加前面视图的静态table的转向剪头指向这个View Controller, ...
- ruby语言是什么东西
1.简介 Ruby是日本的Yukihiro Matsumoto写的,简单易学的面向对象的脚本语言,像perl一样,有丰富的文字处理.系统管理等丰富 功能,但是ruby要简单,容易理解和扩充.跟p ...