在Vue中创建可重用的 Transition的方法


Posted in Javascript onJune 02, 2020

Vue.js中的transition确实很棒。毫无疑问,它们可以非常轻松地让应用程序栩栩如生,但是通常必须在每个项目中从头开始编写它们,甚至还需要引入animate.css之类的CSS库来使它们功能更强大。

如果我们可以将它们封装到组件中,并在多个项目中简单地重用它们,结果会怎样呢?我们将介绍几种定义transition的方法,并深入研究如何使它们真正可重用。

在Vue中创建可重用的 Transition的方法

原始transition组件和CSS

定义transition的最简单方法是使用transition·或transition-group组件。这需要为transition定义一个name`和一些CSS。

<template> 
 <div id="app"> 
 <button v-on:click="show = !show"> 
 Toggle 
 </button> 
 <transition name="fade"> 
 <p v-if="show">hello</p> 
 </transition> 
 </div> 
</template> 
<script> 
export default { 
 name: "App", 
 data() { 
 return { 
 show: true 
 }; 
 } 
}; 
</script> 
<style> 
.fade-enter-active, 
.fade-leave-active { 
 transition: opacity 0.3s; 
} 
.fade-enter, 
.fade-leave-to { 
 opacity: 0; 
} 
</style>
在Vue中创建可重用的 Transition的方法

看起来容易,对吧?然而,这种方法有一个问题。我们不能在另一个项目中真正重用这个transition。

封装transition组件

如果我们将前面的逻辑封装到一个组件中,并将其用作一个组件,结果会怎样呢?

// FadeTransition.vue 
<template> 
 <transition name="fade"> 
 <slot></slot> 
 </transition> 
</template> 
<script> 
export default { 
 
}; 
</script> 
<style> 
.fade-enter-active, 
.fade-leave-active { 
 transition: opacity 0.3s; 
} 
.fade-enter, 
.fade-leave-to { 
 opacity: 0; 
} 
</style> 
 
// App.vue 
 
<template> 
 <div id="app"> 
 <button v-on:click="show = !show"> 
 Toggle transition 
 </button> 
 <fade-transition> 
 <div v-if="show" class="box"></div> 
 </fade-transition> 
 </div> 
</template> 
<script>...</script> 
<style>...</style>

在Vue中创建可重用的 Transition的方法

通过在transition组件中提供一个slot,我们几乎可以像使用基本transition组件一样使用它。这比前面的例子稍微好一点,但是如果我们想要传递其他特定于transition的prop,比如mode或者一些hook,该怎么办呢

封装的包装器transition组件

幸运的是,Vue 中有一个功能,使我们可以将用户指定的所有额外props和监听器传递给我们的内部标签/组件。如果你还不知道,则可以通过$attrs访问额外传递的 props,并将它们与v-bind结合使用以将它们绑定为props。这同样适用于通过$listeners进行的事件,并通过v-on对其进行应用。

// FadeTransition.vue 
 
<template> 
 <transition name="fade" v-bind="$attrs" v-on="$listeners"> 
 <slot></slot> 
 </transition> 
</template> 
<script> 
export default {}; 
</script> 
<style> 
.fade-enter-active, 
.fade-leave-active { 
 transition: opacity 0.3s; 
} 
.fade-enter, 
.fade-leave-to { 
 opacity: 0; 
} 
</style> 
 
// App.vue 
 
... 
 
<fade-transition mode="out-in"> 
 <div key="blue" v-if="show" class="box"></div> 
 <div key="red" v-else class="red-box"></div> 
</fade-transition> 
 
...
在Vue中创建可重用的 Transition的方法

「完整事例地址:https://codesandbox.io/s/yjl1wjyoy1?from-embed 」

现在,我们可以传递普通transition组件可以接受的任何事件和支持,这使得我们的组件更加可重用。但为什么不更进一步,增加通过 prop 轻松定制持续时间的可能性。

显式持续时间 prop

Vue 为transition组件提供了一个duration prop,然而,它是为更复杂的动画链接而设计的,它帮助 Vue 正确地将它们链接在一起。

在我们的案例中,我们真正需要的是通过组件prop控制CSS animation/transition。我们可以通过不在CSS中指定显式的CSS动画持续时间,而是将其作为样式来实现。我们可以借助transition hook来做到这一点,该transition hook与组件生命周期 hook 非常相似,但是它们在过渡所需元素之前和之后被调用。让我们看看效果如何。

// FadeTransition.vue 
 
<template> 
 <transition name="fade" 
  enter-active-class="fadeIn" 
  leave-active-class="fadeOut" 
  v-bind="$attrs" 
  v-on="hooks"> 
 <slot></slot> 
 </transition> 
</template> 
<script> 
export default { 
 props: { 
 duration: { 
 type: Number, 
 default: 300 
 } 
 }, 
 computed: { 
 hooks() { 
 return { 
 beforeEnter: this.setDuration, 
 afterEnter: this.cleanUpDuration, 
 beforeLeave: this.setDuration, 
 afterLeave: this.cleanUpDuration, 
 ...this.$listeners 
 }; 
 } 
 }, 
 methods: { 
 setDuration(el) { 
 el.style.animationDuration = `${this.duration}ms`; 
 }, 
 cleanUpDuration(el) { 
 el.style.animationDuration = ""; 
 } 
 } 
}; 
</script> 
<style> 
@keyframes fadeIn { 
 from { 
 opacity: 0; 
 } 
 to { 
 opacity: 1; 
 } 
} 
.fadeIn { 
 animation-name: fadeIn; 
} 
@keyframes fadeOut { 
 from { 
 opacity: 1; 
 } 
 to { 
 opacity: 0; 
 } 
} 
.fadeOut { 
 animation-name: fadeOut; 
} 
</style>
在Vue中创建可重用的 Transition的方法

「完整事例地址:https://codesandbox.io/s/j4qnjvmwz9?from-embed 」

现在,我们可以控制实际的可见过渡时间,这使我们可重用的过渡变得灵活且易于使用。但是,如何过渡多个元素(如列表项)呢?

Transition group 支持

你想到的最直接的方法可能是创建一个新组件,比如fade-transition-group,然后将当前transition标签替换为transition-group标签,以实现 group transition。如果我们可以在相同的组件中这样做,并公开一个将切换到transition-group实现的group prop,那会怎么样呢?幸运的是,我们可以通过render函数或component和is属性来实现这一点。

// FadeTransition.vue 
 
<template> 
 <component :is="type" 
  :tag="tag" 
  enter-active-class="fadeIn" 
  leave-active-class="fadeOut" 
  move-class="fade-move" 
  v-bind="$attrs" 
  v-on="hooks"> 
 <slot></slot> 
 </component> 
</template> 
<script> 
export default { 
 props: { 
 duration: { 
 type: Number, 
 default: 300 
 }, 
 group: { 
 type: Boolean, 
 default: false 
 }, 
 tag: { 
 type: String, 
 default: "div" 
 } 
 }, 
 computed: { 
 type() { 
 return this.group ? "transition-group" : "transition"; 
 }, 
 hooks() { 
 return { 
 beforeEnter: this.setDuration, 
 afterEnter: this.cleanUpDuration, 
 beforeLeave: this.setDuration, 
 afterLeave: this.cleanUpDuration, 
 leave: this.setAbsolutePosition, 
 ...this.$listeners 
 }; 
 } 
 }, 
 methods: { 
 setDuration(el) { 
 el.style.animationDuration = `${this.duration}ms`; 
 }, 
 cleanUpDuration(el) { 
 el.style.animationDuration = ""; 
 }, 
 setAbsolutePosition(el) { 
 if (this.group) { 
 el.style.position = "absolute"; 
 } 
 } 
 } 
}; 
</script> 
<style> 
@keyframes fadeIn { 
 from { 
 opacity: 0; 
 } 
 to { 
 opacity: 1; 
 } 
} 
.fadeIn { 
 animation-name: fadeIn; 
} 
@keyframes fadeOut { 
 from { 
 opacity: 1; 
 } 
 to { 
 opacity: 0; 
 } 
} 
.fadeOut { 
 animation-name: fadeOut; 
} 
.fade-move { 
 transition: transform 0.3s ease-out; 
} 
</style> 
 
// App.vue 
 
... 
 
<div class="box-wrapper"> 
 <fade-transition group :duration="300"> 
 <div class="box" 
  v-for="(item, index) in list" 
  @click="remove(index)" 
  :key="item" 
 > 
 </div> 
 </fade-transition> 
</div> 
 
...
在Vue中创建可重用的 Transition的方法

「完整事例地址:https://codesandbox.io/s/pk9r5j2257?from-embed 」

[文档中][6]介绍了一个带有transition-group元素的警告。我们基本上必须在元素离开时将每个项目的定位设置为absolute,以实现其他项目的平滑移动动画。我们也必须添加一个move-class并手动指定过渡持续时间,因为没有用于移动的 JS hook。我们将这些调整添加到我们的上一个示例中。

再做一些调整,通过在mixin中提取 JS 逻辑,我们可以将其应用于轻松创建新的transition组件,只需将其放入下一个项目中即可。

Vue Transition

在此之前描述的所有内容基本上都是这个小型 [transition 集合][7]所包含的内容。它有 10 个封装的transition组件,每个约1kb(缩小)。我认为它非常方便,可以轻松地在不同的项目中使用。你可以试一试:)

总结

我们从一个基本的过渡示例开始,并最终通过可调整的持续时间和transition-group支持来创建可重用的过渡组件。我们可以使用这些技巧根据并根据自身的需求创建自己的过渡组件。希望读者从本文中学到了一些知识,并且可以帮助你们建立功能更好的过渡组件。

到此这篇关于在Vue中创建可重用的 Transition的方法的文章就介绍到这了,更多相关vue创建Transition内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JS解决url传值出现中文乱码的另类办法
Apr 08 Javascript
用Js实现的动态增加表格示例自己写的
Oct 21 Javascript
JavaScript实现显示函数调用堆栈的方法
Apr 21 Javascript
超实用的JavaScript代码段 附使用方法
May 22 Javascript
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
Jun 23 Javascript
Javascript 动态改变imput type属性
Nov 01 Javascript
JavaScript基于DOM操作实现简单的数学运算功能示例
Jan 16 Javascript
简述vue中的config配置
Jan 23 Javascript
React如何避免重渲染
Apr 10 Javascript
vue中keep-alive的用法及问题描述
May 15 Javascript
js实现黑白div块画空心的图形
Dec 13 Javascript
ES2020让代码更优美的运算符 (?.) (??)
Jan 04 Javascript
jQuery+Ajax+js实现请求json格式数据并渲染到html页面操作示例
Jun 02 #jQuery
2020淘宝618理想生活列车自动领喵币js脚本的代码
Jun 02 #Javascript
JavaScript实现手机号码 3-4-4格式并控制新增和删除时光标的位置
Jun 02 #Javascript
2020京东618叠蛋糕js脚本(亲测好用)
Jun 02 #Javascript
vue项目在webpack2实现移动端字体自适配功能
Jun 02 #Javascript
React实现类似淘宝tab居中切换效果的示例代码
Jun 02 #Javascript
实例分析javascript中的异步
Jun 02 #Javascript
You might like
PHP5各个版本的新功能和新特性总结
2014/03/16 PHP
php foreach正序倒序输出示例代码
2014/07/01 PHP
php 5.4 全新的代码复用Trait详解
2017/01/05 PHP
php基于PDO实现功能强大的MYSQL封装类实例
2017/02/27 PHP
thinkphp5.0整合phpsocketio完整攻略(绕坑)
2018/10/12 PHP
一个基于jquery的图片切换效果
2010/07/06 Javascript
基于Jquery 解决Ajax请求的页面 浏览器后退前进功能,页面刷新功能实效问题
2010/12/11 Javascript
全面理解面向对象的 JavaScript(来自ibm)
2013/11/10 Javascript
使用JQuery快速实现Tab的AJAX动态载入(实例讲解)
2013/12/11 Javascript
Nodejs使用mysql模块之获得更新和删除影响的行数的方法
2014/03/18 NodeJs
简介JavaScript中setUTCSeconds()方法的使用
2015/06/12 Javascript
jQuery+CSS实现的网页二级下滑菜单效果
2015/08/25 Javascript
浅谈Vuex的状态管理(全家桶)
2017/11/04 Javascript
深入理解es6块级作用域的使用
2019/03/28 Javascript
JS中实现一个下载进度条及播放进度条的代码
2019/06/10 Javascript
ECharts地图绘制和钻取简易接口详解
2019/07/12 Javascript
js简单实现自动生成表格功能示例
2020/06/02 Javascript
解决Antd Table表头加Icon和气泡提示的坑
2020/11/17 Javascript
python web框架学习笔记
2016/05/03 Python
Python格式化日期时间操作示例
2018/06/28 Python
Tensorflow中的placeholder和feed_dict的使用
2018/07/09 Python
Python List cmp()知识点总结
2019/02/18 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
2019/06/26 Python
Python测试线程应用程序过程解析
2019/12/31 Python
解决python 在for循环并且pop数组的时候会跳过某些元素的问题
2020/12/11 Python
Html5移动端div固定到底部实现底部导航条的几种方式
2021/03/09 HTML / CSS
美国电子元器件分销商:Newark element14
2018/01/13 全球购物
英国第一的购买便宜玩具和游戏的在线购物网站:Bargain Max
2018/01/24 全球购物
高尔夫球鞋、服装、手套和装备:FootJoy
2018/12/15 全球购物
军训自我鉴定范文
2014/02/13 职场文书
服装促销活动方案
2014/02/23 职场文书
大学教师师德师风演讲稿
2014/08/22 职场文书
火烧圆明园观后感
2015/06/03 职场文书
Spring Boot 排除某个类加载注入IOC的操作
2021/08/02 Java/Android
Java由浅入深通关抽象类与接口(上篇)
2022/04/26 Java/Android
MySQL实现用逗号进行拼接、以逗号进行分割
2022/12/24 MySQL