Not getting different class names while iterating - vue.js

I am having a v-for loop in my vuejs application. i want each span to have a different class name. For example .spa0, .spa1, .spa3..... How do I do it using index in v-for loop?
I tried something like this:
:class="`spa${index}`"
Some of my code is:
<div>
<span v-for="(t, index) in table_data" :class="`spa${index}`">{{t}}</span>
</div>
I expect each span to have a different class.

If table_data is like this as you stated in the comments:
{
type: 'LDAP',
des: 'LDAP for Demo - Do not edit or delete this App',
api: 'show token',
scim: 'cloud.kapstonellc.com:8082/scim/v2/10VN44ZN',
endis: true,
act: true
}
You should probably iterate over table_data keys instead:
<div>
<span v-for="(key, index) in Object.keys(table_data)" :class="`spa${index}`">
{{ table_data[key] }}
</span>
</div>

Related

Use unknown key in the v-model in vue js for loop

I have a dynamically made object of facets.
An example of the data could be:
facets: {
type: ['type1', 'type2', 'type3'],
color: ['color1', 'color2']
}
I also have an empty object for filters.
I then loop over the facets object and make checkbox groups for each facet. I want the v-model to be filters."name of the facet", so: filters.type and filters.color. I do not know the names forehand. I tried using the key in a loop but that does not work.
My loop looks like this:
<li v-for="(facet, facetKey, facetIndex) in facets" class="filter-item">
<strong>{{ facetKey }}</strong>
<div v-for="(value, valueIndex) in facet" class="form__fieldset" :key="valueIndex">
<div class="form__field-wrap">
<input type="checkbox" v-model="filters[facetKey]" :id="value.toLowerCase().trim()" :value="value">
<label :for="value.toLowerCase().trim()">{{ value }}</label>
</div>
</div>
</li>
If I hardcode v-model to filters.type, It works as intended. Has anyone achieved this type of dynamic v-models?
Populate filters with your facets properties
filters = ref({
...facets.value
})
Here is the playground link to a working example

creating a loop to loop over the componennt created

I have this data which is returning me the labels and every I need to create a component.
The component is already built when I pass the values. Now I want to create it as a for loop so that I can keep on adding entries, and it will create components as needed.
This is what I've tried:
data() {
return {
options: [{
heading: 'Welcome to the Card',
subheading: 'Manage your Profile here'
},
{
heading: 'Pay your bills',
subheading: 'Manage your bills and payments here'
}
]
}
}
I am trying to loop it over like this
<div v-for="(value, key) in options">
<componentName {{key}} = {{value}}/>
</div>
Previously, the above code was like this:
<componentName :heading='Welcome to the Card' :subheading='Manage your Profile here'/>
Which works well but to add more I have to recreate this <componentName which I want to avoid. I want to keep one entry and feed it with array of objects
I'm using Vue2. What am I doing wrong here?
You're very close. Given your data, the template would need to look like:
<div v-for="(option, index) in options" :key="index">
<h3>{{ option.heading }}</h3>
<p>{{ option.subheading}}</p>
</div>
Or, if you've got a custom component, which takes heading and subheading as props:
<componentName
v-for="(option, index) in options"
:key="index"
:heading="option.heading"
:subheading="option.subheading"
/>
If you can share a bit more of your code, I can create a runnable snippet, if that would be helpful.

Anyone can tell me what lenguaje are use in this line of code?

Im whatching a vue.js course and the presentator use this code for an if/else stament on the vue component.
Please if someone can tell me, to understand a way more better the code, im be appreciative.
<template>
<!-- ? = if // : = else -->
<div :class="[task.reminder ? 'reminder' : '', 'task']">
<h3>{{ task.text }}
<i class="fas fa-times"></i>
</h3>
<p>{{ task.day }}</p>
</div>
</template>
<div :class="[task.reminder ? 'reminder' : '', 'task']">
source: https://v2.vuejs.org/v2/guide/class-and-style.html#Array-Syntax
this line will conditionally add array of class that will be joined by a space . So on the first element of the array, it is a ternary operator which depend on task.reminder value, if it is true or something meet the requirement of the ternary, it will add reminder class or an empty string '' which will not be added to the class, and on the index 1 of the array which is task will be added.
Say for example that your task.reminder is true, the div will be render as below:
<div class="reminder task">
if it is false, it will be render as
<div class="task">
{{ task.text }}
source: https://v2.vuejs.org/v2/guide/syntax.html?redirect=true#Text
this is how we render out a variable from vue into the DOM, wrap with {{ and }}

How to setup multiple keys for components in template tag using v-for?

I wanted to render a list using v-for. It's simple enough, the documentation explains almost every use case. I want it to look like that:
<template v-for="(item, index) in items" :key="index">
<CustomComponent :item="item"/>
<Separator v-if="index !== items.length-1"/>
</template>
Unfortunately, the documentation does not say how to set a key for multiple custom components in one v-for.
Obviously, I don't want to include separator to my custom component, because it is used in other places too. Code I have pasted is generating those errors:
'template' cannot be keyed. Place the key on real elements instead.
I can set a key on component and separator using an index but I got errors: Duplicate keys detected: 'x'. This may cause an update error.
For now, I'm doing it like that but it's an ugly hack and would not work with more components in one template.
<template v-for="(item, index) in items">
<CustomComponent :item="item" :key="(index+1)*-1"/>
<Separator v-if="index !== items.length-1" :key="(index+1)"/>
</template>
Example from documentation explains templates on the list with basic components which does not require keys.
Does anyone know how should I do it correctly?
Ps. It is not recommended to use v-if on v-for. Could someone suggest how to change my code not to use v-if but don't render separator under the last element?
Here is how I was able to generate a key -- you could customize the generateKey method to return whatever you like.
<template>
<div>
<div
v-for="(item, index) in items"
:key="generateKey(item, index)"
>Item {{ index }} : {{ item }}</div>
</div>
</template>
<script>
export default {
data() {
return {
items: ["Sun", "Moon", "Stars", "Sky"]
};
},
methods: {
generateKey(item, index) {
const uniqueKey = `${item}-${index}`;
return uniqueKey;
}
}
};
</script>
Working Example: https://codesandbox.io/s/30ojo1683p
I was talking with a friend and he suggested the simplest and in my opinion the best solution. Just add a component prefix to every key e.g:
<template v-for="(item, index) in items">
<CustomComponent :item="item" :key="'custom_component-'+index"/>
<Separator v-if="index !== items.length-1" :key="'separator-'+index"/>
</template>

[Vue warn]: Duplicate keys detected: x. This may cause an update error

I keep getting an error when I add an item to the array which has duplicate id.
i.e.
active_widgets:Array[4]
0:Object
id:1
name:"Text Blocks"
selected:false
set:false
1:Object
id:3
name:"Bibliographies/References"
selected:false
set:false
2:Object
id:1
name:"Text Blocks"
selected:false
set:false
3:Object
id:2
name:"Free Text"
selected:"Test"
set:false
In my scenario, 'id' element may be duplicate because the user can have the same widget on the page multiple times. I want to know if I can suppress or remove the warning that VueJS keeps throwing in the console.
Same key for different v-for loops causing this warning. You can avoid this using different key for different v-for loops.
<div v-for="(item, i) in items" :key="i"></div>
<div v-for="(item, i) in items2" :key="'A'+ i"></div>
<div v-for="(item, i) in items3" :key="'B' + i"></div>
Here, A and B are just sample characters. You can basically use any character instead of those (just for uniqueness).
An alternative method:
Nesting the v-for elements inside any other element also seems to work.
<div>
<div v-for="(item, index) in items" :key="index"></div>
</div>
<div>
<div v-for="(item, index) in items2" :key="index"></div>
</div>
You need to bind to the key with a unique value. Not doing so will cause problems in your application when a change in data for a component with one key updates that component and the other component with the duplicate key.
You should assign a unique key property to each of the items in the active_widgets array and then bind the key to that property.
Without seeing any of your code, I don't know what your unique use case is. But here are a couple ways you could add a unique key property to the items in your array.
Here's an example doing that in the created method.
created() {
this.active_widgets.forEach((item, index) => this.$set(item, 'key', index));
}
If you need to add a unique key when an item is added to this array, you could maintain a counter and increment it each time an addition is made:
let WidgetCount = 0;
export default {
data() {
return { active_widgets: [] }
},
methods: {
addWidget(id, name) {
this.active_widgets.push({
id,
name,
selected: false,
set: false,
key: WidgetCount++
})
}
}
}
use different key name your problem will be solved.
<div v-for="(item, i) in items" :key="i"></div>
<div v-for="(item, j) in items2" :key="j" :data-index="j"></div>
or
<div v-for="(item, i) in items2" :key="'i+item.id" :data-index="i"></div>
<template v-for="it in items">
<li :key="it.id + '-name'">{{it.name}}</li>
</template>
https://github.com/vuejs/vue/issues/7323
<div v-for="(data, index)" in active_widgets" :key="index">
{{data.id}}
{{data.name}}
{{data.selected}}
{{data.set}}
</div>
I solved this by creating a unique key function to add keys to each of my arrays. Then using it in v-for as the key...
<div
class="postBlob"
v-for="{
key,
user,
post,
dateTime
} in localPostData.slice().reverse()"
:key="key"
>
<strong class="userBlobIndy">{{ user }} </strong>
<h2 class="postBlobIndy">
{{ post }}
<p>{{ dateTime }}</p>
</h2>
</div>
you can use this example
<template>
<div >
<div v-for="categori in blogs" id="blog-body" :key="categori.title" >
<h2 >{{categori.title}}</h2>
<h3>{{categori.contact }}</h3>
</div>
</div>
</template>
<script>
export default {
data(){
return{
blogs:[
{title:'this is title 1',contact : ' this is contact for test javascript'},
{title:'this new title ',contact : ' this is contact for vue'},
{title:'this is new title 2',contact : ' this is contact for vue js'}
]
}
},
}
</script>