やりたいこと
Vuetify.jsで、Amazonの検索結果のように複数のカードを配置したページを作ろうと考えています。
要件は以下の通りです。
- カードのサイズは固定
- カードの個数は不定
- ウインドウ(表示領域)の横幅に応じて1行ごとのカードの個数を変える
- カードは全体的には中央揃えにしつつ、複数行にわたる場合は最後の行のカードを左揃えにして他の行と揃える
(Flexbox で全体を中央に配置しつつ最後の行を左揃えにする - Qiita)
やったこと
これを実現するために色々と試行錯誤した結果、以下のようになりました。
ソースコード
html
1<div id="app"> 2 <v-app> 3 <v-container fluid grid-list-xl> 4 <v-layout wrap justify-space-around> 5 <v-flex v-for="image in images" :key="image.num"> 6 <v-card color="gray" dark width="300px"> 7 <v-card-text>{{ image.num }}</v-card-text> 8 <v-card-media :src="image.src" height="400px"></v-card-media> 9 <v-card-actions> 10 <v-btn icon><v-icon>arrow_left</v-icon></v-btn> 11 <v-spacer></v-spacer> 12 <v-btn icon><v-icon>favorite</v-icon></v-btn> 13 <v-spacer></v-spacer> 14 <v-btn icon><v-icon>arrow_right</v-icon></v-btn> 15 </v-card-actions> 16 </v-card> 17 </v-flex> 18 <v-flex v-for="image in images" :key="image.num" class="flex-empty"> 19 <div></div> 20 </v-flex> 21 </v-layout> 22 </v-container> 23 </v-app> 24</div>
scss
1.flex { 2 flex-grow: 0; 3} 4 5.flex-empty { 6 height: 0 !important; 7 padding-top: 0 !important; 8 padding-bottom: 0 !important; 9 10 div { 11 width: 300px; 12 } 13}
js
1const PAGE_NUM = 5 2 3new Vue({ 4 el: '#app', 5 data: () => ({ 6 images: Array.from(new Array(PAGE_NUM)).map((e, i) => ({ 7 num: i + 1, 8 src: `https://picsum.photos/300/400?image=${i + 1}` 9 })) 10 }) 11})
https://codepen.io/munieru_jp/pen/jpdJNV
表示
疑問
これでやりたいことは一応実現できているのですが、Vuetifyのコンポートのスタイルを上書きしていたり、空の要素を追加したりしているのがあまり美しくないと感じています。
Vuetifyのコンポートを普通に使うだけで実現できるのであればそれがベターですが、そのような方法はありますでしょうか。
あなたの回答
tips
プレビュー