小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
TIP 👉 滚滚长江东逝水,浪花淘尽英雄。是非成败转头空,青山依旧在,几度夕阳红。罗贯中《三国演义·卷首词》
前言
在我们日常项目开发中,我们经常会做一些翻转功能,所以封装了这款功能组件。翻转组件
属性
1. isBack
- 是否显示反面
- 值为布尔类型
- 默认值:false
2. duration
- 动画时长
- 值为数值类型,单位:毫秒
- 默认值:325
3. direction
- 翻转方向
- 值为‘x’或者‘y’
- x:沿x轴方向翻转,y:沿y轴方向翻转
- 默认值:‘y’
插槽
1. front
- 正面内容插槽
2. back
- 反面内容插槽
示例代码
<template>
<div class="flip-demo">
<div class="flip-wrap">
<BaseFlip :isBack="true" :duration="350" direction="y">
<img slot="front" src="./img/card-a.png" alt="">
<img slot="back" src="./img/card-b.png" alt="">
</BaseFlip>
</div>
<div class="flip-wrap">
<BaseFlip :isBack="false" :duration="240" direction="x">
<img slot="front" src="./img/card-a.png" alt="">
<img slot="back" src="./img/card-b.png" alt="">
</BaseFlip>
</div>
</div>
</template>
<script>
import BaseFlip from '@/components/base/flip/index.vue'
export default {
name: 'FlipDemo',
components: {
BaseFlip
}
}
</script>
<style lang="scss" scoped>
.flip-demo{
.flip-wrap{
position: relative;
width: 254px;
height: 440px;
margin: 60px auto;
img{
width: 100%;
height: 100%;
}
}
}
</style>
实现flip.vue
<!-- 翻转组件 -->
<template>
<div class="card" @click="doSwitch">
<div class="flip" :class="[frontStatus]" :style="durationStyle">
<slot name="front"></slot>
</div>
<div class="flip" :class="[backStatus]" :style="durationStyle">
<slot name="back"></slot>
</div>
</div>
</template>
<script>
export default {
name: 'Flip',
props: {
// 是否反面
isBack: {
type: Boolean,
default: false
},
// 动画时长,单位:毫秒
duration: {
type: Number,
default: 325
},
// 方向, x:沿x轴方向翻转,y:沿y轴方向翻转
direction: {
type: String,
default: 'y'
}
},
data () {
let data = {
backFlag: this.isBack,
frontStatus: '',
backStatus: ''
}
if (this.isBack) {
data.frontStatus = 'hidde'
} else {
data.backStatus = 'hidde'
}
return data
},
computed: {
durationStyle () {
return {
animationDuration: `${this.duration}ms`
}
}
},
watch: {
backFlag (flag) {
if (flag) {
this.frontStatus = 'out-' + this.direction
setTimeout(() => {
this.$set(this, 'backStatus', 'in-' + this.direction)
}, this.duration)
} else {
this.backStatus = 'out-' + this.direction
setTimeout(() => {
this.$set(this, 'frontStatus', 'in-' + this.direction)
}, this.duration)
}
}
},
methods: {
doSwitch () {
this.backFlag = !this.backFlag
this.$emit('flip', this.backFlag)
}
}
}
</script>
<style lang="scss" scoped>
.card, .flip{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.flip{
backface-visibility: hidden;
transform: translateX(0);
}
.in-x {
animation-name: flipintobottom;
// animation-duration: 325ms;
animation-timing-function: ease-out;
}
.out-x {
transform: rotateX(-90deg) scale(.9);
animation-name: flipouttotop;
animation-timing-function: ease-in;
// animation-duration: 325ms;
}
.in-y {
animation-name: flipintoright;
// animation-duration: 325ms;
animation-timing-function: ease-out;
}
.out-y {
transform: rotateY(-90deg) scale(.9);
animation-name: flipouttoleft;
animation-timing-function: ease-in;
// animation-duration: 325ms;
}
@keyframes flipouttoleft {
from { transform: rotateY(0); }
to { transform: rotateY(-90deg) scale(.9); }
}
@keyframes flipintoright{
from { transform: rotateY(90deg) scale(.9); }
to { transform: rotateY(0); }
}
@keyframes flipouttotop {
from { transform: rotateX(0); }
to { transform: rotateX(-90deg) scale(.9); }
}
@keyframes flipintobottom{
from { transform: rotateX(90deg) scale(.9); }
to { transform: rotateX(0); }
}
.hidde{
opacity: 0;
}
</style>
「欢迎在评论区讨论」