アコーディオンの開閉状態を各skillごとに別に管理して、その状態を参照してv-showを切り替える必要があると思います。
例えば以下のようなコードでしょうか
サンプルコード
一応2パターン載せておきます。①のほうがロジックはシンプルになりますが、管理する状態が増えます。
②は管理する状態は減りますが、ロジックは若干複雑になります。
今回の場合は①のほうが読みやすいかもしれません。
①開閉状態を別の連想配列として管理するパターン
js
1<template>
2 <div>
3 <div
4 v-for="skill in skills"
5 class="accordion"
6 v-bind:key="skill.id"
7 v-bind:style="{ border: '8px' + ' ' + 'solid' + ' ' + skill.bgColor, backgroundColor: skill.bgColor }"
8 >
9 <div
10 class="label"
11 v-on:click="toggleAccordion(skill.id)"
12 v-bind:style="{ backgroundColor: skill.bgColor }"
13 >
14 <h2>
15 {{ skill.name }}
16 <i
17 class="fa fa-angle-down label-icon"
18 v-bind:class="{ rotate : show[skill.id] }"
19 ></i>
20 </h2>
21 </div>
22 <transition name="slide">
23 <div class="box" v-show="show[skill.id]">
24 <!-- <img v-bind:src="require(`../assets/images/${skill.name}.png`)"> -->
25 <p>{{ skill.description }}</p>
26 </div>
27 </transition>
28 </div>
29 </div>
30</template>
31
32<script>
33export default {
34 name: "HelloWorld",
35 data() {
36 return {
37 skills: [
38 {
39 id: 1,
40 name: "HTML・CSS",
41 bgColor: "red",
42 description: `
43 text
44 `
45 },
46 {
47 id: 2,
48 name: "JavaScript",
49 bgColor: "gold",
50 description: `
51 text
52 `
53 },
54 {
55 id: 3,
56 name: "Vue.js",
57 bgColor: "forestgreen",
58 description: `
59 text
60 `
61 },
62 {
63 id: 4,
64 name: "Sass",
65 bgColor: "hotpink",
66 description: `
67 text
68 `
69 },
70 {
71 id: 5,
72 name: "Firebase",
73 bgColor: "orange",
74 description: `
75 text
76 `
77 },
78 {
79 id: 6,
80 name: "Git・Github",
81 bgColor: "black",
82 description: `
83 text
84 `
85 },
86 {
87 id: 7,
88 name: "webpack",
89 bgColor: "skyblue",
90 description: `
91 text
92 `
93 }
94 ],
95 show: {
96 1: false,
97 2: false,
98 3: false,
99 4: false,
100 5: false,
101 6: false,
102 7: false
103 }
104 };
105 },
106 methods: {
107 toggleAccordion(skillId) {
108 this.show[skillId] = !this.show[skillId];
109 }
110 }
111};
112</script>
113
114<!-- Add "scoped" attribute to limit CSS to this component only -->
115<style lang="scss" scoped>
116.accordion {
117 width: 400px;
118 .label {
119 height: 30px;
120 margin-bottom: 10px;
121 text-align: center;
122 color: white;
123 cursor: pointer;
124 h2 {
125 font-weight: bold;
126 line-height: 30px;
127 }
128 .label-icon {
129 margin-left: 10px;
130 }
131 }
132 .box {
133 overflow: hidden;
134 background-color: white;
135 width: 100%;
136 display: flex;
137 img {
138 display: block;
139 width: 100px;
140 height: 100px;
141 }
142 }
143}
144.rotate {
145 transform: rotate(180deg);
146 transition: 0.3s;
147}
148.slide-enter-active {
149 transition-duration: 0.3s;
150 transition-timing-function: ease-in;
151}
152.slide-leave-active {
153 transition-duration: 0.3s;
154 transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
155}
156.slide-enter-to,
157.slide-leave {
158 max-height: 100px;
159 overflow: hidden;
160}
161.slide-enter,
162.slide-leave-to {
163 max-height: 0;
164 overflow: hidden;
165}
166</style>
167
②開閉状態を既存のskills配列の中で管理するパターン
js
1<template>
2 <div>
3 <div
4 v-for="skill in skills"
5 class="accordion"
6 v-bind:key="skill.id"
7 v-bind:style="{ border: '8px' + ' ' + 'solid' + ' ' + skill.bgColor, backgroundColor: skill.bgColor }"
8 >
9 <div
10 class="label"
11 v-on:click="toggleAccordion(skill)"
12 v-bind:style="{ backgroundColor: skill.bgColor }"
13 >
14 <h2>
15 {{ skill.name }}
16 <i class="fa fa-angle-down label-icon" v-bind:class="{ rotate : skill.show }"></i>
17 </h2>
18 </div>
19 <transition name="slide">
20 <div class="box" v-show="skill.show">
21 <!-- <img v-bind:src="require(`../assets/images/${skill.name}.png`)"> -->
22 <p>{{ skill.description }}</p>
23 </div>
24 </transition>
25 </div>
26 </div>
27</template>
28
29<script>
30export default {
31 name: "HelloWorld",
32 data() {
33 return {
34 skills: [
35 {
36 id: 1,
37 show: false, // skillごとに開閉状態を保持
38 name: "HTML・CSS",
39 bgColor: "red",
40 description: `
41 text
42 `
43 },
44 {
45 id: 2,
46 show: false,
47 name: "JavaScript",
48 bgColor: "gold",
49 description: `
50 text
51 `
52 },
53 {
54 id: 3,
55 show: false,
56 name: "Vue.js",
57 bgColor: "forestgreen",
58 description: `
59 text
60 `
61 },
62 {
63 id: 4,
64 show: false,
65 name: "Sass",
66 bgColor: "hotpink",
67 description: `
68 text
69 `
70 },
71 {
72 id: 5,
73 show: false,
74 name: "Firebase",
75 bgColor: "orange",
76 description: `
77 text
78 `
79 },
80 {
81 id: 6,
82 show: false,
83 name: "Git・Github",
84 bgColor: "black",
85 description: `
86 text
87 `
88 },
89 {
90 id: 7,
91 show: false,
92 name: "webpack",
93 bgColor: "skyblue",
94 description: `
95 text
96 `
97 }
98 ]
99 };
100 },
101 methods: {
102 toggleAccordion: function(skill) {
103 this.skills.find(s => s.id === skill.id).show
104 = !this.skills.find(s => s.id === skill.id).show
105 }
106 }
107};
108</script>
109
110<!-- Add "scoped" attribute to limit CSS to this component only -->
111<style lang="scss" scoped>
112.accordion {
113 width: 400px;
114 .label {
115 height: 30px;
116 margin-bottom: 10px;
117 text-align: center;
118 color: white;
119 cursor: pointer;
120 h2 {
121 font-weight: bold;
122 line-height: 30px;
123 }
124 .label-icon {
125 margin-left: 10px;
126 }
127 }
128 .box {
129 overflow: hidden;
130 background-color: white;
131 width: 100%;
132 display: flex;
133 img {
134 display: block;
135 width: 100px;
136 height: 100px;
137 }
138 }
139}
140.rotate {
141 transform: rotate(180deg);
142 transition: 0.3s;
143}
144.slide-enter-active {
145 transition-duration: 0.3s;
146 transition-timing-function: ease-in;
147}
148.slide-leave-active {
149 transition-duration: 0.3s;
150 transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
151}
152.slide-enter-to,
153.slide-leave {
154 max-height: 100px;
155 overflow: hidden;
156}
157.slide-enter,
158.slide-leave-to {
159 max-height: 0;
160 overflow: hidden;
161}
162</style>
163