Reputation: 1610
I want to render 3 videos in a bootstrap row with vue.js.
I need to open <div class="row">
and close this tag each 3 videos in order to wrap the wrap them inside.
I don't know how to do that with vueJS?
HTML markup:
<div class="container" id="video-list">
<div v-for="(item, index) in items"><!--how to open this tag only if index%3==0?-->
<div class="row">
<div class="col-md-4 col-sm-4 ">
<h3>{{item}} {{index}}</h3>
<video class="video-js vjs-default-skin vjs-16-9 vjs-big-play-centered" controls
preload="auto" width="640" height="264" poster="video-poster.png"
data-setup="{}">
<source :src="'video/' + item" type='video/mp4'>
</video>
</div>
</div> <!--how to close this tag only if index%3==0?-->
</div>
</div>
Javascript code:
var videos = new Vue({
el: '#video-list',
data: {
items: JSON.parse(result)
}
});
I saw Conditional Rendering instructions but when I apply this to this div class="row"
this hide the child tags that contain videos!
In my case, I don't want to manage tag rendering, I need to be able to open/close conditionally a tag element.
Upvotes: 1
Views: 1798
Reputation: 1677
So here is an answer to a question to divide an array into chunks, I used it to achieve the behavior you need, and here is the example:
// https://stackoverflow.com/a/10456644/4738332
Object.defineProperty(Array.prototype, 'chunk', {value: function(n) {
return Array.from(Array(Math.ceil(this.length/n)), (_,i)=>this.slice(i*n,i*n+n));
}});
Vue.component('app-row', {
props:['items'],
template:`
<div class="row">
<div class="item" v-for="item in items">{{item}}</div>
</div>
`
})
new Vue({
el:"#app",
data:{
items: [1,2,3,4,5,6,7,8,9,10]
},
computed:{
getRowsItems(){
return this.items.chunk(3)
}
}
})
.row{
background-color: green;
margin: 20px;
padding: 10px;
}
.item{
background-color: blue;
margin: 4px;
color: white;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<div id="app">
<app-row v-for="rowItems in getRowsItems" :items="rowItems"></app-row>
</div>
Upvotes: 0
Reputation: 86
You can process the items to a matrix and iterate into it.
var videos = new Vue({
el: '#video-list',
data: function() {
var items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
var rows = [];
while (items.length > 0) {
rows.push(items.splice(0, 3));
}
return {
rows: rows
};
}
});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div class="container" id="video-list">
<div v-for="(row, i) in rows" class="row">
<div v-for="(col, j) in row" class="col-md-4 col-sm-4">
<h3>{{ col + "(" + j + " " + i + ")"}}</h3>
</div>
</div>
</div>
Upvotes: 6
Reputation: 13389
Unfortunately you can't do like that. You'll need to make something like this:
<div class="container" id="video-list">
<div v-for="(item, index) in items">
<!--how to open this tag only if index%3==0?-->
<div class="row" v-if="index % 3 === 0">
<div class="col-md-4 col-sm-4 ">
<h3>{{item}} {{index}}</h3>
<video class="video-js vjs-default-skin vjs-16-9 vjs-big-play-centered" controls preload="auto" width="640" height="264" poster="video-poster.png" data-setup="{}">
<source :src="'video/' + item" type='video/mp4'>
</video>
</div>
</div>
<!--how to close this tag only if index%3==0?-->
<!-- Notice, here you don't have the row anymore -->
<div class="col-md-4 col-sm-4 " v-else>
<h3>{{item}} {{index}}</h3>
<video class="video-js vjs-default-skin vjs-16-9 vjs-big-play-centered" controls preload="auto" width="640" height="264" poster="video-poster.png" data-setup="{}">
<source :src="'video/' + item" type='video/mp4'>
</video>
</div>
</div>
</div>
Maybe you will create a small component to not duplicate the code inside the row.
Upvotes: 0