Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Marina Mosti
Marina Mosti

Posted on • Edited on

     

Hands-on Vue.js for Beginners (Part 4)

Welcome back! 🤩

Last time we took at conditional rendering withv-if andv-show. This time we will learn how to loop through arrays and objects and create an element for each one of the items in them. We will also apply some of the concepts we have learned before.

v-for

v-for is one of the fundamental directives ofVue.js, and once you understand how it works the extension of what you can build inside your apps will grow exponentially.

v-for is, simply put, afor loop. If you don't yet know what this means, a for loop is a piece of code that gets executed one time per each element in a group - which in turn is usually anArray or anObject.

We're going to start with an empty slate today so that everything we do has a clear purpose. Here's a copy of our baseindex.html file for you to copy and paste into your editor.

<html><head><title>Vue 101</title></head><body><divid="app"></div><scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script>constapp=newVue({el:'#app',data:{},methods:{}});</script></body></html>
Enter fullscreen modeExit fullscreen mode

Let's start by creating a simple list, an array, that we can loop to output its content. We will create a property inside ourdata object, calledgames. Feel free to change the titles to your own personal favorites 🙃🎮

data:{games:['Super Mario 64','The Legend of Zelda Ocarina of Time','Secret of Mana','Super Metroid']},
Enter fullscreen modeExit fullscreen mode

Awesome! Now that we have our array set up, let's create a sad and simple<ul> element where will display it. For the sake of example, let's keep it simple for now.

<divid="app"><ul><li>Game title here</li></ul></div>
Enter fullscreen modeExit fullscreen mode

Ok, looking good! Now we have to tellVue that we want to output as many<li> elements inside the<ul> as needed to loop through our whole array.

In other languages, and even in vanilla JavaScript, you may be used to doing something that looks similar to this:

<?phpforeach($gamein$games):?><li><?phpecho$game;?></li><?phpendforeach;?>
Enter fullscreen modeExit fullscreen mode

Where the loopencloses the element(s) it's going to output or print out.

InVue we declare ourv-for directive on TOP of the element we want to loop. Make these changes to your<li> and we'll dissect them after.

<ul><liv-for="game in games">{{game}}</li></ul>
Enter fullscreen modeExit fullscreen mode

Let's take a look.

  1. v-for was added directly to the<li>, not the<ul> as we saw earlier. This reads: "For eachgame in mygames array, please make a new<li> inside these<ul> tags.
  2. Note thatgames is the property that we added earlier with the array inside ourdata, so we have to use this variable name.
  3. The variablegame (singular) is defined by us, we could useitem,game,title or whatever we feel like. But be sure to understand that this*game* in games is what you will be using as a variable inside your loop.
  4. Finally, inside our<li> tag we're outputting the contents of ourgame variable, so while the loop is running for each of our games, this will output the string into the<li>.

Run your app inside the browser, and you should see your list of items being outputted to the screen.

Taking it up a notch

So far, so good?v-for is actually a very simple concept, and this example is super boring. So how about we make things a bit more complicated, by making our array include some objects, and also applying somev-ifs inside our list?

First things first, let's update ourgames property with some more interesting data.

data:{games:[{name:'Super Mario 64',console:'Nintendo 64',rating:4},{name:'The Legend of Zelda Ocarina of Time',console:'Nintendo 64',rating:5},{name:'Secret of Mana',console:'Super Nintendo',rating:4},{name:'Fallout 76',console:'Multiple',rating:1},{name:'Super Metroid',console:'Super Nintendo',rating:6}]},
Enter fullscreen modeExit fullscreen mode

As always feel free to use your own favorite titles. PS. Super Metroid's rating of 6 is not a typo, it's just THAT good - and I'm biased. 😬 Also, Bethesda, you should be ashamed.cough Anyways.

If you run your app this point it will not particularly break, but it will just output the objects in a string format, which is not pretty. In fact, we're going to scratch our<ul> approach completely, and use a<div> to output our information. (Don't worry, it'll still be ugly).

Update your whole<div>:

<divid="app"><divv-for="game in games"><h1>{{ game.name }} -<small>{{ game.console }}</small></h1><spanv-for="star in game.rating">❤️</span><divv-if="game.rating > 5">Wow, this game must be<b>REALLY</b> good</div></div></div>
Enter fullscreen modeExit fullscreen mode

WOAH. Ok, maybe not, but don't worry, you already know everything you need to understand what's happening here.

  1. div v-for="game in games" Same old, we're going to loop ourgames array prop and store each game in thegame variable.
  2. h1. Ok, sogame is an object, which in turn holds its own properties,name,console andrating. Inside the<h1> we're going to output the game's *name:game.name. And the console:game.console. As you can see now,v-for is not limited to outputting just a single element as we saw before with theli, but you can actually output as much HTML as you need.
  3. The nestedv-for. So inside thespan element we actually have a nestedv-for loop (which is TOTALLY ok to do), except it's a little different, we're not looping an array or an object. I didn't LIE to you, maybe just withheld some information - like for example, you can actually loop a numeric value (in this casegame.rating and the loop will count up from1 till it reaches the value of the rating. Simple?
  4. Finally,v-if. We are going to output a<div> tag inside our loopIF the condition is met, so if and only if the current game's rating is greater than 5. Take a guess which?

Go ahead and run this again in your browser and behold the awesomeness of not bothering with CSS.

What if I don't need a wrapping DIV?

If at any point you find yourself making a bunch of<div> elements simply to wrap up yourv-for loops, there's a special HTML tag you can use to help your case.<template></template>

If you, for example, remove the wrapping<div> and change it for<template> take a look at your developer console and you'll see that the<h1> and<span> elements are not wrapped by anything.

<template> is special, becauseVue will treat it as a wrapper element but it won't be rendered into the HTML when we execute it, so you can safely use it to wrap a bunch of other elements logically for the loop without affecting your markup.

The :key attribute

One final thing that I purposely left for the end. The:key attribute.

When you are looping through elements withv-forVue.js has NO clue how to track your elements for reactivity, because it can't "tell apart" one object from the other. What this means for you is that sinceVue can't do this, it will re-render the WHOLE section of the page that is being created by this loop. In our case it's a very small section and the performance hit would probably be minimal, but it's something that you should keep in mind - and just do it for best practice.

Now, how do we use it?

:key expects some string it'll use to "name" or "track" the element, so we need to give it a unique identifier. In the case of ourgames it's simple, we can do:

<divv-for="game in games":key="game.name">
Enter fullscreen modeExit fullscreen mode

I'm pretty certain that we're not going to have the same game twice in this list, so this is pretty safe. Anid if you have data coming from a database is alsoideal to use here.

If you are curious about the intricacies of:key you can always take a look at the documentation.Key's docs

In fact, now that you have gotten this far I can't stress enough the importance of getting acquainted with the documentation.Vue.js 's docs are impressively good, and very very clear with code examples, the documentation team does a fantastic job to keep them updated and clear - big shout out to all of them.

Final code

Here's the final code, just in case.

<html><head><title>Vue 101</title></head><body><divid="app"><divv-for="game in games":key="game.name"><h1>{{ game.name }} -<small>{{ game.console }}</small></h1><spanv-for="star in game.rating">❤️</span><divv-if="game.rating > 5">Wow, this game must be<b>REALLY</b> good</div></div></div><scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script>constapp=newVue({el:'#app',data:{games:[{name:'Super Mario 64',console:'Nintendo 64',rating:4},{name:'The Legend of Zelda Ocarina of Time',console:'Nintendo 64',rating:5},{name:'Secret of Mana',console:'Super Nintendo',rating:4},{name:'Fallout 76',console:'Multiple',rating:1},{name:'Super Metroid',console:'Super Nintendo',rating:6}]}});</script></body></html>
Enter fullscreen modeExit fullscreen mode

Challenge

This time you get a challenge if you wish to accept it. Add a@click listener to the<span> which outputs the game's rating, and increase the ranking by1 with each click for that UNIQUE game. You already know everything you need to achieve this 😉.

Tip: You'll need to pass thegame you're looping to the click function, and inspect it.

Good luck!

Top comments(23)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
namstel profile image
Namstel
I'm a web developer and father from The Netherlands. I mostly do Frontend Web development, but I'm also known to dabble in PHP, MySQL and AWS. I'm interested in learning Vue and NodeJS.
  • Location
    Haarlem
  • Education
    Bachelor of IT
  • Work
    Web developer at WebConcern
  • Joined
• Edited on• Edited

Thanks for the tutorial, Marina. Here's my solution:

HTML:

<spanv-for="star in game.rating"@click="increaseRating(game)"></span>

JS bit:

methods:{increaseRating(game){game.rating++;}},

Now on to the next! :D

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

Yay, thanks for reading!

CollapseExpand
 
lukmanarifs profile image
Lukman Arif Sanjani
  • Joined

surprised with the other answer.. short and simple...
why i make it complicated... LOL

addRating (i) {      this.$set(this.games[i], 'rating', this.games[i].rating + 1)    }

btw thanks Marina, nice tutorial

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

All ways lead to Rome-^ Thanks for reading! <3

CollapseExpand
 
akwetey profile image
Jonathan Akwetey
I'm a passionate developer
  • Location
    Accra
  • Work
    Fullstack developer at Fundihub
  • Joined

great one again. i'm accepting the challenge. i will post my answer soon

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

w00t!

CollapseExpand
 
akwetey profile image
Jonathan Akwetey
I'm a passionate developer
  • Location
    Accra
  • Work
    Fullstack developer at Fundihub
  • Joined

Alt text of image

Thread Thread
 
akwetey profile image
Jonathan Akwetey
I'm a passionate developer
  • Location
    Accra
  • Work
    Fullstack developer at Fundihub
  • Joined

hey marina please check it and let me know of any improvements or corrections. Thanks

Thread Thread
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

Hey Jonathan, awesome job! I wasn't expecting you to catch on the (game, index) since i didn't cover it on the tutorial - but job well done finding that out on your own! :)

Thread Thread
 
akwetey profile image
Jonathan Akwetey
I'm a passionate developer
  • Location
    Accra
  • Work
    Fullstack developer at Fundihub
  • Joined

thanks. i will be looking forward to more challanges that pushes me to learn more. I hope you will cover the (game, index) in a different tutorial.

Thread Thread
 
agredalex profile image
Alex Ágreda
  • Email
  • Location
    San Salvador, El Salvador
  • Education
    Universidad de El Salvador
  • Work
    Technical Leader at FOCUS ITO
  • Joined

@click="game.rating += 1", adding this on the span also works

CollapseExpand
 
emmanuelnkechi5 profile image
Enkay💗
I'm a passionate frontend web developer
  • Location
    Nigeria
  • Work
    Frontend Developer at Starthub Innovation
  • Joined

HTML:

❤️

js:

methods: {
increaseRatings(game) {
const rate= game.rating++;
this.game.rating = rate;
}
}

CollapseExpand
 
lincxx profile image
Jeremy Lincoln
  • Location
    TN
  • Education
    BS in Comp Sci
  • Work
    Lead Programmer
  • Joined


<span v-for="star in game.rating" @click="game.rating+=1">❤️</span>

CollapseExpand
 
pwnchaurasia profile image
Pawan Chaurasia
Not your regular fullstack developer next door.
  • Location
    Bengaluru
  • Education
    bachelors of technology
  • Work
    FullStack Python Django developer at Anlyz
  • Joined

My Solution for the challenge
thepracticaldev.s3.amazonaws.com/i...

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

It works, but it's a little overkill :) You can pass the whole 'game' object to the function, that way you don't have to.find on the array. Also, be careful with==, as a best practice try to use=== that way you won't run into very hard to understand bugs with types! :D

CollapseExpand
 
pwnchaurasia profile image
Pawan Chaurasia
Not your regular fullstack developer next door.
  • Location
    Bengaluru
  • Education
    bachelors of technology
  • Work
    FullStack Python Django developer at Anlyz
  • Joined

noted. Thanks

CollapseExpand
 
neutrino2211 profile image
Mainasara Al-amin Tsowa
Fullstack Dev, IT security nerd and IoT obsessor
  • Location
    Abuja, Nigeria
  • Work
    Back-end developer
  • Joined

LOL Fallout 76 not spared here either. Nice post though, you really did not leave any stone unturned

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

:D Well they really messed up. Also, thanks!

CollapseExpand
 
asuliman501 profile image
AhmedSuliman
I'm a front-end Developer
  • Location
    India
  • Work
    Frontend Developer at None
  • Joined

Thanks a lot for sharing v-for. I'm still a bit confused in a few things you've done above.I am a beginner in Vue.js :) Please keep blogging .

CollapseExpand
 
ericstolzervim profile image
Eric Stolzervim
  • Joined

Pass game as a parameter.
Then can have ...

methods: {
addRating(game) {game.rating +=1 }
}

So don't need "this."

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

This is another way to do it :)

CollapseExpand
 
irochkaz profile image
Iryna Zaletko
  • Location
    Belarus
  • Joined

please tell me, the v-key attribute should be visible in the markup?thnk u
prntscr.com/smsw3e

prntscr.com/smswmk

CollapseExpand
 
marinamosti profile image
Marina Mosti
Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

Hey Iryna, no it shouldn't be rendered to the markup as it is internal to Vue

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Marina Mosti is a full-stack web developer with over 14 years of experience in the field. She enjoys mentoring other women on JavaScript and her favorite framework, Vue.
  • Joined

More fromMarina Mosti

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp