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:
JavaScript
x
15
15
1
<div id="planflex" :style="style">
2
<div class="block">
3
<h2> {{ action_id }} </h2>
4
</div>
5
<div class="block">
6
<img
7
:src="require(`../assets/legos/2x${size}${color}.png`)"
8
alt="legos"
9
id="lego">
10
</div>
11
<div class="block " :id="action_id" @click="choose()">
12
<h3> {{ actor }} </h3>
13
</div>
14
</div>
15
Can you please tell me how can I achieve that properly? thanks in advance.
The FlipCard.vue
Vue component I have tried to develop:
JavaScript
1
36
36
1
<template>
2
<div id="flashcard" class="container" @dblclick="toggleCard()">
3
4
<transition name="flip">
5
<div v-bind:key="flipped" class="card">
6
{{ flipped ? back : front }}
7
</div>
8
</transition>
9
</div>
10
</template>
11
12
<script>
13
export default {
14
name: "FlipCard",
15
props: {
16
front: {
17
type: Object,
18
required: true
19
},
20
back: {
21
type: Object,
22
required: true
23
},
24
flipped: {
25
type: Boolean,
26
default: false,
27
},
28
},
29
methods: {
30
toggleCard() {
31
this.flipped = !this.flipped;
32
},
33
}
34
}
35
</script>
36
Style.css
JavaScript
1
101
101
1
<style>
2
body {
3
font-family: 'Montserrat', sans-serif;
4
text-align: center;
5
}
6
7
ul {
8
padding-left: 0;
9
display: flex;
10
flex-flow: row wrap;
11
}
12
13
li {
14
list-style-type: none;
15
padding: 10px 10px;
16
transition: all 0.3s ease;
17
}
18
19
.container {
20
max-width: 100%;
21
padding: 2em;
22
}
23
24
.card {
25
display: block;
26
width: 150px;
27
height: 175px;
28
padding: 80px 50px;
29
background-color: #51aae5;
30
border-radius: 7px;
31
margin: 5px;
32
text-align: center;
33
line-height: 27px;
34
cursor: pointer;
35
position: relative;
36
color: #fff;
37
font-weight: 600;
38
font-size: 20px;
39
-webkit-box-shadow: 9px 10px 22px -8px rgba(209,193,209,.5);
40
-moz-box-shadow: 9px 10px 22px -8px rgba(209,193,209,.5);
41
box-shadow: 9px 10px 22px -8px rgba(209,193,209,.5);
42
will-change: transform;
43
}
44
45
li:hover{
46
transform: scale(1.1);
47
}
48
49
li:nth-child(-n+3) .card{
50
background-color: #e65f51;
51
}
52
53
li:nth-child(2n+1) .card{
54
background-color: #a17de9;
55
}
56
57
li:nth-child(4n) .card{
58
background-color: #feca34;
59
}
60
61
li:nth-child(5n-2) .card{
62
background-color: #51aae5;
63
}
64
65
li:nth-child(4n+4) .card{
66
background-color: #feca34;
67
}
68
69
li:nth-child(-7n+7) .card{
70
background-color: #e46055;
71
}
72
73
.delete-card {
74
position: absolute;
75
right: 0;
76
top: 0;
77
padding: 10px 15px;
78
opacity: .4;
79
transition: all 0.5s ease;
80
}
81
82
.delete-card:hover, .error {
83
opacity: 1;
84
transform: rotate(360deg);
85
}
86
87
.flip-enter-active {
88
transition: all 0.4s ease;
89
}
90
91
.flip-leave-active {
92
display: none;
93
}
94
95
.flip-enter, .flip-leave {
96
transform: rotateY(180deg);
97
opacity: 0;
98
99
}
100
</style>
101
Advertisement
Answer
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
JavaScript
1
4
1
<div v-bind:key="flipped" class="card">
2
<component :is="cardSide" />
3
</div>
4
JavaScript
1
14
14
1
<script>
2
import cardFront from "@/components/cardFront.vue";
3
import cardBack from "@/components/cardBack.vue";
4
5
export default {
6
computed: {
7
cardSide() {
8
if (this.flipped) return cardFront;
9
else return cardBack;
10
},
11
}
12
};
13
</script>
14
more detailed codesandbox here.
Another option is to use slots to display dynamic component content.
Parent component
JavaScript
1
9
1
<flip-card>
2
<template v-slot:front>
3
<cardFront />
4
</template>
5
<template v-slot:back>
6
<cardBack />
7
</template>
8
</flip-card>
9
flipCard.vue
JavaScript
1
11
11
1
<template>
2
<div id="flashcard" class="container" @click="toggleCard()">
3
<transition name="flip">
4
<div v-bind:key="flipped" class="card">
5
<slot v-if="!flipped" name="front"></slot>
6
<slot v-else name="back"></slot>
7
</div>
8
</transition>
9
</div>
10
</template>
11
another more detailed codesandbox