vuejs dynamically bind text in class attribute - vue.js

I am trying to dynamically change the text of an fa icon depending on what an object in the data (iterating in for loop) contains:
<ul id="example-1">
<li v-for="item in cards" :key="item.id">
<i class="fa fa-cc-{{item.brand}} fa-2x" style="color:black"></i> {{ item.brand }}
</li>
</ul>
This doesn't seem to work

You can make class as dynamic attribute as below
:class="`fa fa-cc-${item.brand}`"

I suppose that would be the correct way of doing it (string concatenation):
<ul id="example-1">
<li v-for="item in cards" :key="item.id">
<i :class="'fa fa-cc-'+item.brand+' fa-2x'" style="color:black"></i> {{ item.brand }}
</li>
</ul>
or different syntax with ECMAScript 6 template literals:
<ul id="example-1">
<li v-for="item in cards" :key="item.id">
<i :class="`fa fa-cc-${item.brand} fa-2x`" style="color:black"></i> {{ item.brand }}
</li>
</ul>
You can see that I used dynamic class binding.

Related

Wrapper element for for loop

I'm currently expanding my horizon by trying out Vuejs.
I'm creating a navigation with data coming from my Vue instance, and I have the following code:
<ul class="nav">
<li class="nav-item" v-for="navLink in navLinks" :key="navLink.id">
<a class="nav-link" :href="navLink.url">{{ navLink.name }}</a>
</li>
</ul>
Now even though this works perfectly fine, I have seen the following two examples in videos instead:
<ul class="nav">
<template v-for="navLink in navLinks">
<li class="nav-item">
<a class="nav-link" :href="navLink.url">{{ navLink.name }}</a>
</li>
</template>
</ul>
<ul class="nav">
<div v-for="navLink in navLinks" :key="navLink.id">
<li class="nav-item">
<a class="nav-link" :href="navLink.url">{{ navLink.name }}</a>
</li>
</div>
</ul>
I'm asking myself which one of these is best practice.
Now from what I've learned, one should always (if possible) set a :key in a for loop. This is not possible on the tag, therefore I would think this option is the worse.
But what about option 3 and mine? Is there any difference? Is it just personal preference or is there an actual reason on why to choose one or the other.
Ty
The only difference I spot between the first and the third options is that you'd wrap each list item in an additional div. You don't need those wrappers unless you want to use this nesting for styling purposes.
Your example is perfectly fine. Just make sure ids you use for keys are unique.
Also avoid using v-if and v-for on the same element and rather add v-if on the parent
I think you should always put a key property in your for loop.
Say you have nothing to work with for an ID (some item.name could potentially be duplicated?) just use this:
<div v-for="(item, index) in items)" :key="index">
{{ item.name }}
</div>
index in this case is just the index of the items array.
So yours will be rendered like:
<ul class="nav">
<li class="nav-item" :key="navLink.id">
<a class="nav-link" :href="navLink.url">{{ navLink.name }}</a>
</li>
...
<li class="nav-item" :key="navLink.id">
<a class="nav-link" :href="navLink.url">{{ navLink.name }}</a>
</li>
</ul>
Whereas the third one will be:
<ul class="nav">
<div :key="navLink.id">
<li class="nav-item">
<a class="nav-link" :href="navLink.url">{{ navLink.name }}</a>
</li>
</div>
...
<div :key="navLink.id">
<li class="nav-item">
<a class="nav-link" :href="navLink.url">{{ navLink.name }}</a>
</li>
</div>
</ul>
I would say it's a bit verbose to wrap a <li> inside a <div> in each one of them.
Yours is fine, all of them indeed are going to work well, but the third one may have problems with custom css, since it's a wrapper for the tag.
The template is an alternative as it is stated in the docs.
You've set the key at the li tag, as long as you're following the guide for mantaining state with keys, it's fine.

show subcategories on hover if they exist

something like <div class="submenu" v-if="SUB_CATS> or v-if="SUB_CATS !== 0" doesnt work, please
help me understand
now on hover i have empty div, if there no subcats
<ul class="menu-categories">
<li class="menu-item" v-for="category in MAIN_CATS"
:key="category.id">
<nuxt-link :to="`/category/${category.id}`" class="menu-button">
{{ category.title }}
</nuxt-link>
<div class="submenu">
<ul class="menu-sub-list">
<li class="menu-item"
v-for="sub in SUB_CATS(category.id)"
:key="sub.id">
<nuxt-link :to="`/category/${sub.id}`" class="menu-button">{{ sub.title }}</nuxt-link>
</li>
</ul>
</div>
</li>
</ul>

How can I use a v-for value in to nuxt link?

I have a loop that loops through an associative array that has text with links
links: {'Amount' : '/about', 'Contact' : '/contact'}
How can I use the value from my for loop in my nuxt-link? So to="value"?
<ul class="link">
<li v-for="(link, text) in links" :key="text" :value="link">
<nuxt-link to=link>{{key}}</nuxt-link>
</li>
</ul>
Your code is almost correct. In order to use your JavaScript objects you just have to use model binding just like the following.
<ul class="link">
<li v-for="(link, text) in links" :key="text" :value="link">
<nuxt-link :to="link">{{key}}</nuxt-link>
</li>
</ul>
Please note the :to="link".
Try this :
<ul class="link">
<li v-for="(link, index) in links" :key="index">
<nuxt-link :to="link"> {{ index }}</nuxt-link>
</li>
</ul>

How do I toggle (hide/unhide) child elements of dynamically added components with v-for

The following renders a header text and some child elements.
What I would like to accomplish is that the child elements toggle (hide/unhide) when the header is clicked. So in below example, when Spanish01 is clicked, all its children should be hidden and when its clicked again the should reappear.
I tried to find a similar case on the internet but could not find any. All help is welcome
<div id="dashboard">
<ul class="collection with-header">
<li class="collection-header"><h4>Cards</h4></li>
<li v-for="card in cards" v-bind:key="card.id" class="collection-item">
<div class="chip">{{card.group_name}}</div>
<ul class="collection with-header">
<li v-for="(value, index) in card.group" v-bind:key="index" class="collection-item">
<ul>
<li>
front: {{value.front}}
</li>
<li>
back: {{value.back}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
You can simply put an extra variable on each of your cards. Then you can do something like this:
<div id="dashboard">
<ul class="collection with-header">
<li class="collection-header"><h4>Cards</h4></li>
<li v-for="card in cards" v-bind:key="card.id" class="collection-item">
<div class="chip" #click="card.shown = !card.shown>{{card.group_name}}</div>
<ul class="collection with-header" v-show="card.shown">
<li v-for="(value, index) in card.group" v-bind:key="index" class="collection-item">
<ul>
<li>
front: {{value.front}}
</li>
<li>
back: {{value.back}}
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Obviously, you have to alter your variable cards so it contains the shown attribute by default. As an alternative, you can set up a different variable that contains the shown status and use some unique id to look up the value instead.

vue transition groups with vue2-animate not working

I've been struggling with making vue transitions work.
I'm using vue2-animate along with vue to create some simple transition effect for when list items appear/disappear.
Here's the block:
<transition-group class="mt-2"
name="fadeLeft"
v-if="type == selectedType"
tag="ul">
<li class="mb-2" v-bind:key="category.name"
v-for="(category, index) in getCategoriesForType(type)"
#click="selectCategory(category)">
{{ category.name }}
</li>
</transition-group>
It doesn't add any effects when I try it. It simply shows/ hides the lists.
I've tested/confirmed that the animation is working in different component, but cannot figure out why the above code doesn't do any animations.
Here's the block that was working:
<ul class="list-group notes" v-if="notes.length > 0">
<transition-group name="fadeLeft">
<li v-for="(note, index) in notes" v-bind:key="note" class="list-group-item" v-on:remove="notes.splice(index, 1)">
<button class="close" #click="removeNote(index)"><span class="fa fa-times"></span></button>
{{ note.text }}
</li>
</transition-group>
</ul>