在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 相关文章推荐
Extjs中DisplayField的日期或者数字格式化扩展
Sep 03 Javascript
js常用代码段整理
Nov 30 Javascript
javascript判断并获取注册表中可信任站点的方法
Jun 01 Javascript
用JavaScript实现页面重定向功能的教程
Jun 04 Javascript
jQuery解决input超多的表单提交
Aug 10 Javascript
AngularJS实用开发技巧(推荐)
Jul 13 Javascript
jQuery实现的购物车物品数量加减功能代码
Nov 16 Javascript
JavaScript实现星星等级评价功能
Mar 22 Javascript
node.js实现的装饰者模式示例
Sep 06 Javascript
Webpack框架核心概念(知识点整理)
Dec 22 Javascript
vue移动端监听滚动条高度的实现方法
Sep 03 Javascript
js+canvas实现转盘效果(两个版本)
Sep 13 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
php引用地址改变变量值的问题
2012/03/23 PHP
教你如何快捷的使用cmd访问mysql小技巧
2014/05/26 PHP
ThinkPHP中session函数详解
2016/09/14 PHP
PHP调试及性能分析工具Xdebug详解
2017/02/09 PHP
thinkphp5.0自定义验证规则使用方法
2017/11/16 PHP
在js中单选框和复选框获取值的方式
2009/11/06 Javascript
javascript 二进制运算技巧解析
2012/11/27 Javascript
12种不宜使用的Javascript语法整理
2013/11/04 Javascript
javascript获取四位数字或者字母的随机数
2015/01/09 Javascript
javascript将异步校验表单改写为同步表单
2015/01/27 Javascript
JQuery跳出each循环的方法
2015/04/16 Javascript
很棒的js Tab选项卡切换效果
2016/08/30 Javascript
jQuery在ie6下无法设置select选中的解决方法详解
2016/09/20 Javascript
javascript设置文本框光标的方法实例小结
2016/11/04 Javascript
基于JavaScript实现右键菜单和拖拽功能
2016/11/28 Javascript
js微信扫描二维码登录网站技术原理
2016/12/01 Javascript
详解如何在vue中使用sass
2017/06/21 Javascript
node内置调试方法总结
2018/02/22 Javascript
JavaScript指定断点操作实例教程
2018/09/18 Javascript
javascript实现函数柯里化与反柯里化过程解析
2019/10/08 Javascript
js键盘事件实现人物的行走
2020/01/17 Javascript
微信小程序使用GoEasy实现websocket实时通讯
2020/05/19 Javascript
vue项目打包后提交到git上为什么没有dist这个文件的解决方法
2020/09/16 Javascript
Javascript 模拟mvc实现点餐程序案例详解
2020/12/24 Javascript
Python 开发Activex组件方法
2009/11/08 Python
python 多线程将大文件分开下载后在合并的实例
2018/11/09 Python
Python人工智能之路 jieba gensim 最好别分家之最简单的相似度实现
2019/08/13 Python
CSS3制作炫酷的自定义发光文字
2016/03/28 HTML / CSS
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
Mamaearth官方网站:印度母婴护理产品公司
2019/10/06 全球购物
经典C++面试题一
2016/11/06 面试题
元旦晚会感言
2014/03/12 职场文书
2015年社会治安综合治理工作总结
2015/04/10 职场文书
公务员岗前培训心得体会
2016/01/08 职场文书
《西游记》读后感(3篇)
2019/09/20 职场文书
CSS中理解层叠性及权重如何分配
2022/12/24 HTML / CSS