在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 相关文章推荐
30分钟就入门的正则表达式基础教程
Feb 25 Javascript
extjs表格文本启用选择复制功能具体实现
Oct 11 Javascript
简介JavaScript中的setHours()方法的使用
Jun 11 Javascript
高性能JavaScript DOM编程(1)
Aug 11 Javascript
jQuery语法小结(超实用)
Dec 31 Javascript
javascript下使用Promise封装FileReader
Feb 19 Javascript
jQuery实现拖拽页面元素并将其保存到cookie的方法
Jun 12 Javascript
Javascript打印局部页面实例
Jun 21 Javascript
jQuery实现的自动加载页面功能示例
Sep 04 Javascript
JS排序之选择排序详解
Apr 08 Javascript
JS实现进度条动态加载特效
Mar 25 Javascript
Vue关于组件化开发知识点详解
May 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自动判断字符集并转码的详解
2013/06/26 PHP
php中的Base62类(适用于数值转字符串)
2013/08/12 PHP
WordPress的主题编写中获取头部模板和底部模板
2015/12/28 PHP
[原创]解决wincache不支持64位PHP5.5/5.6的问题(提供64位wincache下载)
2016/06/22 PHP
修改yii2.0用户登录使用的user表为其它的表实现方法(推荐)
2017/08/01 PHP
得到jQuery detach()后节点中的某个值实现代码
2013/02/05 Javascript
js 判断计算字符串长度/判断空的简单方法
2013/08/05 Javascript
JavaScript中setInterval的用法总结
2013/11/20 Javascript
jQuery遮罩层实现方法实例详解(附遮罩层插件)
2015/12/08 Javascript
Jquery使用小技巧汇总
2015/12/29 Javascript
JavaScript焦点事件、鼠标事件和滚轮事件使用详解
2016/01/15 Javascript
浅谈js的url解析函数封装
2016/06/28 Javascript
js实现添加可信站点、修改activex安全设置,禁用弹出窗口阻止程序
2016/08/17 Javascript
jQuery用FormData实现文件上传的方法
2016/11/21 Javascript
jquery使用EasyUI Tree异步加载JSON数据(生成树)
2017/02/11 Javascript
angular.js 路由及页面传参示例
2017/02/24 Javascript
微信通过页面(H5)直接打开本地app的解决方法
2017/09/09 Javascript
关于Vue单页面骨架屏实践记录
2017/12/13 Javascript
Webpack优化配置缩小文件搜索范围
2017/12/25 Javascript
js原生实现移动端手指滑动轮播图效果的示例
2018/01/02 Javascript
Angular6使用forRoot() 注册单一实例服务问题
2019/08/27 Javascript
python实现逆序输出一个数字的示例讲解
2018/06/25 Python
使用 Python 实现微信群友统计器的思路详解
2018/09/26 Python
python爬虫基础教程:requests库(二)代码实例
2019/04/09 Python
django 实现将本地图片存入数据库,并能显示在web上的示例
2019/08/07 Python
python中with用法讲解
2020/02/07 Python
Java byte数组操纵方式代码实例解析
2020/07/22 Python
如何使用Python进行PDF图片识别OCR
2021/01/22 Python
全球酒店预订网站:Hotels.com
2016/08/10 全球购物
巴西最大的家具及装饰用品店:Mobly
2017/10/11 全球购物
会计电算化专业应届大学生求职信
2013/10/22 职场文书
检讨书范文大全
2015/05/07 职场文书
《黄山奇石》教学反思
2016/02/18 职场文书
涨工资申请书应该怎么写?
2019/07/08 职场文书
项目中Nginx多级代理是如何获取客户端的真实IP地址
2022/05/30 Servers
详解SQL报错盲注
2022/07/23 SQL Server