How to Loop Over a Data Collection in Vue JS with the V For Directive
In this video, we are going to learn how to have to have multiple components render on the page and then we're also going to learn about one of the very key directives that you're most likely going to be using quite a bit as you build out Vue applications.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Right now our entire app Vue component has really been just located right here on the page.

large

Let's scroll down because I think that this particular part of the page where you have these four logos is perfect for being able to understand how to work with the V For directive.

large

So the v-fordirective in Vue allows you to iterate and loop over a data collection and then render that on the page. This is something that is incredibly common.

If you're building out, say a search engine, like we're going to do later on in this course and you're calling an outside API, and you don't know if that API has one element or it adds 1000 elements you need to be able to loop through that and then show it on the page.

That's what we're going to do except right now we're going to have form elements and we're going to see how we can render them on the page loop through and then also pass the data from the component directly to the HTML page.

Let's switch over into the code and I'm going to scroll down to where we'll want this to be located. We have this alternate_options_images class. This is going to be where we want to build it eventually, so I'm going to delete this implementation here and we're just going to use the Vue one.

Now let's create a div. And attached to this div, I want to add a class or an ID so I'm going to go with ID and let's just call this logoList, and then write testing inside of this, just to test it out.

index.html

<div id="logoList">
    {{ testing }}
</div>

Now in our app.js file we can scroll all the way to the bottom. Whenever you're working with multiple components what you can do is right at the very bottom you can just say new Vue, and this is going to create a new Vue component.

Inside of it we're going to treat it exactly how we treated this Vue component except the difference is we're going to have different elements, data, and methods so we can treat these completely independent of each other.

app.js

new Vue({
    el: "#logoList",
    data: {
        testing: "heyyyyy"
    }
});

Now let's save all of this and look at our browser.

large

You can see that it says "heyyyyy", which means that this is working perfectly. Our new component is still there and now let's make sure that we have not affected anything with our old one and it looks like everything else is still working.

So this is one of the really powerful things about Vue is it gives you the ability to work on a component by component basis,so that you can structure and organize your code however you need to.

The important thing is make sure that the data is wrapped up inside of a component and that it's not it's not really referencing the other ones unless you want it to.

Later on in the course you will see exactly how we can do that. Right now we have this logo list we have this testing data component we don't really need that. Anytime you and I comment something out inside of a template in Vue you can use the normal HTML commenting syntax.

That is going to be commented out so that nothing is rendered on the template. So far so good. Now that we have that let's add some data. This is going to be actual real data. Instead of just testing, we're going to build an array with objects inside of it.

So we're going to copy our logos from index.html, and this will be similar to how we would work with an API, and we'll paste these into our logoList, inside of our data.

app.js

new Vue({
    el: "#logoList",
    data: {
        testing: "heyyyyy",
        logos: [

            <img class="image_logos" src="images/ds_circle_logo.png">
            <img class="image_logos" src="images/ds_square_logo.png">
            <img class="text_logos" src="images/ds_icon_text_logo.png">
            <img class="text_logos" src="images/ds_text_logo.png">
        ]
    }
});

Now it's not going to look like HTML, so we need to convert this to resemble an object.

app.js

new Vue({
    el: "#logoList",
    data: {
        testing: "heyyyyy",
        logos: [

            { className>: "image_logos", imgSource: "images/ds_circle_logo.png" }
            { className>: "image_logos", imgSource: "images/ds_square_logo.png" }
            { className>: "text_logos", imgSource: "images/ds_icon_text_logo.png" }
            { className>: "text_logos", imgSource: "images/ds_text_logo.png" }
        ]
    }
});

This is going to be what our object looks like. If we're working with an outside API this would be very similar to the JSON data we'd be getting. Let's save it. Now our data has been moved outside of the HTML and now it is inside of our Vue component, and because of that we have access to it.

So let's come back to our index.html and see how this is going to work. Anytime that you have some kind of data collection that you've hardcoded like we have in our current component file.

Typically what this would be is data that you're getting from an outside source, so this could be an outside API or any kind of service that sends you a collection of data.

This is so common that Vue created a directive for it. So whenever you need to iterate and create multiple elements on a page what you can do is use the normal <img> tag, but instead of just saying class and then the src, we're going to say v-for.

index.html

<div id="logoList">
    <!-- {{ testing }} -->
    <img v-for="logo in logos" src="" alt="">
</div>

Whenever you create a v-for directive, it's going to go and try to find the data collection that you've created, for us it's logos.
Now, from there what we're doing is creating a loop. We've made an iterator variable named logo.

It really doesn't matter what we call it, and you could call it anything you want, but the common convention in Vue and pretty much in every programming language out there is if you're iterating over some kind of collection and the collection has a plural name usually you're going to use the singular name.

So in this case, it would be logo for our collection of logos. This is going to give us access to each one of the items as it's being looped over.

Now, if we go into our source here, remember that we can access this source by adding a colon in front of it and which will make it an attribute directive. So this means that inside of source I can access that URL.

So let's switch over to our component in app.js. You can see that the first time we iterate over our logos, logo will be equal to our first item, but when it iterates the second time, it's going to be equal to our second item, and so on and so forth.

What we're going to do is grab this image source.

I will say this was one of the times I really fell in love with Vue when I was originally teaching to myself. Let's add in our source.

index.html

<div id="logoList">
    <!-- {{ testing }} -->
    <img v-for="logo in logos" :src="logo.imgSource" alt="">
</div>

The reason we're building it like this is so I don't have to call image multiple times because all of this has to be dynamic,because we don't know how many times this will need to loop over the data.

Now, because of this directive, I now have access to all of the data that I need. Let's save this and check it out.

large

You can see a giant daily smartie logo, and then you can also see these other logos. Now it's not supposed to look like this, but at least we know that part of our implementation is working.

We know that through our directive here, we are able to grab the logo and the image source, so that's pretty cool. We also know that it's iterating over each one of the logos in the data element.

Now what we can do is we can pass in a className. You may have noticed that each one of these elements in our index.html has a class. Through our directive we can pass that data through.

index.html

<div id="logoList">
    <!-- {{ testing }} -->
    <img v-for="logo in logos" :src="logo.imgSource" :class="logo.className">
</div>

Let's check this out.

large

That's gotten us a little closer to what we want, but it's still not exactly what we want. The reason for that is because you may have noticed the wrapper div here has this alternate_options_images class associated with it so let's just grab that and we can add that directly to our wrapper component.

index.html

<div id="logoList" class="alternate_options_images">
    <!-- {{ testing }} -->
    <img v-for="logo in logos" :src="logo.imgSource" :class="logo.className">
</div>

So now I hit save and you can see that now this is working perfectly.

large

So we have an identical implementation, but we have it now using a Vue component and just a couple lines of code as opposed to having to hardcode everything in.

Now if you're building a completely static website where your only goal is to render out some HTML to the page, then this is perfectly fine, but usually when you're using a tool like to Vue, your entire system needs to be much more dynamic and so that's what these directives allow for.

This allows for you to build out this single line of code with this directive and then have it go and handle the logic for you. So it is going to handle the looping process.

You have access to each one of the data elements inside of the collection that you're looping over, just like we do in our project, and then you can render that onto the screen.

So in summary that is how you can use multiple Vue components on the same page as well as working with the v-for directive in Vue.

Resources