アコーディオンの開閉状態を各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 >
33 export 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 >
30 export 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