I want to achieve a Flip card component like the one here by developing a generic Vue Component, but I'm confused about how can I assign a whole face component (front/back) as a back or front face of the card, and how can I lock the flipping property (as an option), an example of the face (front/back) is:
<div id="planflex" :style="style">
<div >
<h2> {{ action_id }} </h2>
</div>
<div >
<img
:src="require(`../assets/legos/2x${size}${color}.png`)"
alt="legos"
id="lego">
</div>
<div :id="action_id" @click="choose()">
<h3> {{ actor }} </h3>
</div>
</div>
Can you please tell me how can I achieve that properly? thanks in advance.
The FlipCard.vue
Vue component I have tried to develop:
<template>
<div id="flashcard" @dblclick="toggleCard()">
<transition name="flip">
<div v-bind:key="flipped" >
{{ flipped ? back : front }}
</div>
</transition>
</div>
</template>
<script>
export default {
name: "FlipCard",
props: {
front: {
type: Object,
required: true
},
back: {
type: Object,
required: true
},
flipped: {
type: Boolean,
default: false,
},
},
methods: {
toggleCard() {
this.flipped = !this.flipped;
},
}
}
</script>
Style.css
<style>
body {
font-family: 'Montserrat', sans-serif;
text-align: center;
}
ul {
padding-left: 0;
display: flex;
flex-flow: row wrap;
}
li {
list-style-type: none;
padding: 10px 10px;
transition: all 0.3s ease;
}
.container {
max-width: 100%;
padding: 2em;
}
.card {
display: block;
width: 150px;
height: 175px;
padding: 80px 50px;
background-color: #51aae5;
border-radius: 7px;
margin: 5px;
text-align: center;
line-height: 27px;
cursor: pointer;
position: relative;
color: #fff;
font-weight: 600;
font-size: 20px;
-webkit-box-shadow: 9px 10px 22px -8px rgba(209,193,209,.5);
-moz-box-shadow: 9px 10px 22px -8px rgba(209,193,209,.5);
box-shadow: 9px 10px 22px -8px rgba(209,193,209,.5);
will-change: transform;
}
li:hover{
transform: scale(1.1);
}
li:nth-child(-n 3) .card{
background-color: #e65f51;
}
li:nth-child(2n 1) .card{
background-color: #a17de9;
}
li:nth-child(4n) .card{
background-color: #feca34;
}
li:nth-child(5n-2) .card{
background-color: #51aae5;
}
li:nth-child(4n 4) .card{
background-color: #feca34;
}
li:nth-child(-7n 7) .card{
background-color: #e46055;
}
.delete-card {
position: absolute;
right: 0;
top: 0;
padding: 10px 15px;
opacity: .4;
transition: all 0.5s ease;
}
.delete-card:hover, .error {
opacity: 1;
transform: rotate(360deg);
}
.flip-enter-active {
transition: all 0.4s ease;
}
.flip-leave-active {
display: none;
}
.flip-enter, .flip-leave {
transform: rotateY(180deg);
opacity: 0;
}
</style>
CodePudding user response:
Your card face looks good to put into a new component and then flipCard.vue can display that component, front or back, as a dynamic component
flipCard.vue
<div v-bind:key="flipped" >
<component :is="cardSide" />
</div>
<script>
import cardFront from "@/components/cardFront.vue";
import cardBack from "@/components/cardBack.vue";
export default {
computed: {
cardSide() {
if (this.flipped) return cardFront;
else return cardBack;
},
}
};
</script>
more detailed codesandbox here.
Another option is to use slots to display dynamic component content.
Parent component
<flip-card>
<template v-slot:front>
<cardFront />
</template>
<template v-slot:back>
<cardBack />
</template>
</flip-card>
flipCard.vue
<template>
<div id="flashcard" @click="toggleCard()">
<transition name="flip">
<div v-bind:key="flipped" >
<slot v-if="!flipped" name="front"></slot>
<slot v-else name="back"></slot>
</div>
</transition>
</div>
</template>
another more detailed codesandbox