如何让 Vue 和 Bootstrap 4 每行显示 3 张卡片
Posted
技术标签:
【中文标题】如何让 Vue 和 Bootstrap 4 每行显示 3 张卡片【英文标题】:How to make Vue and Bootstrap 4 show 3 cards per row 【发布时间】:2018-10-11 16:31:09 【问题描述】:我认为标题说明了一切,如果您看一下我的小提琴,我正在尝试遍历产品并每行打印 3 次引导卡,但是我得到一个,然后是 2,然后您可以看到它添加一个新的列,它发生了几次,然后你会得到一个向右偏移 2 的空白空间......
所以我需要一些关于 vue 或我的 css 或两者的帮助。我认为可能需要发生的只是在index mod 3 = 0
时打印div
和row
和col
类,但我不知道如何用vue 做到这一点。
HTML
<div id="app">
<div class="row">
<div class="col-md-12">
<h1 class="text-center">Products</h1>
<hr />
</div>
</div>
<img v-if="loading" src="https://i.imgur.com/JfPpwOA.gif" />
<section v-else style="margin-left: 10px;">
<div v-for="(product, index) in products.slice(0, 15)">
<!-- if we are 3 cards wide start a new row -->
<div :class="'row':(index % 3 === 0)">
<div :class="'col-md-12':(index % 3 === 0)">
<div class="card" style="width: 16rem; float:left;">
<img class="card-img-top" :src="product.thumbnailUrl" >
<div class="card-body">
<h5 class="card-title">Product index</h5>
<p class="card-text">Product index - product.title</p>
<button v-on:click="addProductToCart(product)" class="btn btn-primary">Add To Cart</button>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
JS
var prodData = [
"albumId": 1,
"id": 1,
"title": "accusamus beatae ad facilis cum similique qui sunt",
"url": "http://placehold.it/600/92c952",
"thumbnailUrl": "http://placehold.it/150/92c952"
,
"albumId": 1,
"id": 2,
"title": "reprehenderit est deserunt velit ipsam",
"url": "http://placehold.it/600/771796",
"thumbnailUrl": "http://placehold.it/150/771796"
,
"albumId": 1,
"id": 3,
"title": "officia porro iure quia iusto qui ipsa ut modi",
"url": "http://placehold.it/600/24f355",
"thumbnailUrl": "http://placehold.it/150/24f355"
,
"albumId": 1,
"id": 4,
"title": "culpa odio esse rerum omnis laboriosam voluptate repudiandae",
"url": "http://placehold.it/600/d32776",
"thumbnailUrl": "http://placehold.it/150/d32776"
,
"albumId": 1,
"id": 5,
"title": "natus nisi omnis corporis facere molestiae rerum in",
"url": "http://placehold.it/600/f66b97",
"thumbnailUrl": "http://placehold.it/150/f66b97"
,
"albumId": 1,
"id": 6,
"title": "accusamus ea aliquid et amet sequi nemo",
"url": "http://placehold.it/600/56a8c2",
"thumbnailUrl": "http://placehold.it/150/56a8c2"
,
"albumId": 1,
"id": 7,
"title": "officia delectus consequatur vero aut veniam explicabo molestias",
"url": "http://placehold.it/600/b0f7cc",
"thumbnailUrl": "http://placehold.it/150/b0f7cc"
,
"albumId": 1,
"id": 8,
"title": "aut porro officiis laborum odit ea laudantium corporis",
"url": "http://placehold.it/600/54176f",
"thumbnailUrl": "http://placehold.it/150/54176f"
,
"albumId": 1,
"id": 9,
"title": "qui eius qui autem sed",
"url": "http://placehold.it/600/51aa97",
"thumbnailUrl": "http://placehold.it/150/51aa97"
];
new Vue(
el: "#app",
data()
return
loading: false,
cart: []
,
methods:
addProductToCart: function(product)
this.cart.push(product);
console.log(this.cart);
,
created()
this.loading = true;
this.products = prodData;
this.loading = false;
)
FIDDLE
【问题讨论】:
【参考方案1】:您可以简单地使用 Vue v-for
重复列(而不是 .row
)...
v-for
应该在列上。使用 .col-md-4
每行 3 张卡片。 Bootstrap 将允许列换行,因此您无需重复 row
divs...
https://jsfiddle.net/vbpb4me5/
<div class="row">
<div class="col-md-4" v-for="(product, index) in products.slice(0, 15)">
<div class="card h-100">
<img class="card-img-top" :src="product.thumbnailUrl" >
<div class="card-body">
<h5 class="card-title">Product index</h5>
<p class="card-text">Product index - product.title</p>
<button v-on:click="addProductToCart(product)" class="btn btn-primary">Add To Cart</button>
</div>
</div>
</div>
</div>
这会创建一个proper grid structure (row>col)。另外注意row
应该放在container
或者container-fluid
中,防止出现水平滚动条。
Codeply demo
相关:Vue three columns of checkboxes in Bootstrap 4
【讨论】:
【参考方案2】:您的代码会产生意想不到的结果,例如:
<div>
<div class="row">Your card</div>
<div class="">Your card</div>
<div class="">Your card</div>
<div class="row">Your card</div>
</div>
另一种解决方案是将您的一维数组更改为二维,然后使用嵌套循环来达到您的目标。
下面是一维数组转二维数组的函数。
get2DArrary: function(arr)
let newArr = [];
while(arr.length) newArr.push(arr.splice(0,3))
return newArr
以下是一个示例:
var prodData = [
"albumId": 1,
"id": 1,
"title": "accusamus beatae ad facilis cum similique qui sunt",
"url": "http://placehold.it/600/92c952",
"thumbnailUrl": "http://placehold.it/150/92c952"
,
"albumId": 1,
"id": 2,
"title": "reprehenderit est deserunt velit ipsam",
"url": "http://placehold.it/600/771796",
"thumbnailUrl": "http://placehold.it/150/771796"
,
"albumId": 1,
"id": 3,
"title": "officia porro iure quia iusto qui ipsa ut modi",
"url": "http://placehold.it/600/24f355",
"thumbnailUrl": "http://placehold.it/150/24f355"
,
"albumId": 1,
"id": 4,
"title": "culpa odio esse rerum omnis laboriosam voluptate repudiandae",
"url": "http://placehold.it/600/d32776",
"thumbnailUrl": "http://placehold.it/150/d32776"
,
"albumId": 1,
"id": 5,
"title": "natus nisi omnis corporis facere molestiae rerum in",
"url": "http://placehold.it/600/f66b97",
"thumbnailUrl": "http://placehold.it/150/f66b97"
,
"albumId": 1,
"id": 6,
"title": "accusamus ea aliquid et amet sequi nemo",
"url": "http://placehold.it/600/56a8c2",
"thumbnailUrl": "http://placehold.it/150/56a8c2"
,
"albumId": 1,
"id": 7,
"title": "officia delectus consequatur vero aut veniam explicabo molestias",
"url": "http://placehold.it/600/b0f7cc",
"thumbnailUrl": "http://placehold.it/150/b0f7cc"
,
"albumId": 1,
"id": 8,
"title": "aut porro officiis laborum odit ea laudantium corporis",
"url": "http://placehold.it/600/54176f",
"thumbnailUrl": "http://placehold.it/150/54176f"
,
"albumId": 1,
"id": 9,
"title": "qui eius qui autem sed",
"url": "http://placehold.it/600/51aa97",
"thumbnailUrl": "http://placehold.it/150/51aa97"
];
new Vue(
el: "#app",
data()
return
loading: false,
cart: []
,
methods:
addProductToCart: function(product)
this.cart.push(product);
console.log(this.cart);
,
get2DArrary: function(arr)
let newArr = [];
while(arr.length) newArr.push(arr.splice(0,3))
return newArr
,
created()
this.loading = true;
this.products = prodData;
this.loading = false;
)
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<div id="app">
<div class="row">
<div class="col-md-12">
<h1 class="text-center">Products</h1>
<hr />
</div>
</div>
<img v-if="loading" src="https://i.imgur.com/JfPpwOA.gif" />
<section v-else style="margin-left: 10px;">
<div v-for="(row, rowIndex) in get2DArrary(products.slice(0, 15))" :key="rowIndex" class="row">
<div v-for="(product, productIndex) in row" :key="productIndex" class="col-md-4">
<!-- if we are 3 cards wide start a new row -->
<div>
<div class="card" style="width: 16rem; float:left;">
<img class="card-img-top" :src="product.thumbnailUrl" >
<div class="card-body">
<h5 class="card-title">Product index</h5>
<p class="card-text">Product index - product.title</p>
<button v-on:click="addProductToCart(product)" class="btn btn-primary">Add To Cart</button>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
【讨论】:
以上是关于如何让 Vue 和 Bootstrap 4 每行显示 3 张卡片的主要内容,如果未能解决你的问题,请参考以下文章
如何让 React.js 和 Bootstrap 4 模态轮播始终在打开时显示第一张图像