How can I get the second value in a v-for loop? - vue.js

So I've got an Object namely:
test:{price: 9, qty:1}
How can I loop through this object and only get the second value namely the qty?
JS:
new Vue({
el: '#app',
data: {
test:{price: 9, qty:1}
}
HTML:
<div v-for="(value, key, index) in test>
{{ value[1] }}
</div>

Since test is an object and you want to access just a single property, so there is no need to loop here you can simply access the object property using . dot notation like:
<div>
{{ test.qty }}
</div>
Demo:
new Vue({
el: '#app',
data: {
test: {
price: 9,
qty: 1
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<div id="app">
<div class="card p-2">
Qty: {{ test.qty }}
</div>
</div>

Related

Range slider how to make step size change in vue.js

<template>
<Slider v-model="[0, 2500]" :min="0" :max="2500" :step="50" />
</template>
I need the steps to be like [50, 100, 250] but not the single value i.e 50
Can anybody help me with this
You can use a simple input range with your desired values. Only the v-model is important to create the two-way-data-binding.
new Vue({
el: '#app',
data: {
selectedValue: 0
}
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.16/dist/vue.js"></script>
<div id='app'>
<input type="range" min="0" max="2500" step="50" v-model="selectedValue">
<p>selected value: {{ selectedValue }}</p>
</div>

Attribute binding using vue.js

I want to bind an image using binding attribute. But reason is that when i run my code it show the Unexpected identifier error
this is my index.html file code
<div id='app'>
<h2>{{product}}</h2>
<div class="flex-container">
<div class="product">
<div class="product-image">
<img v-bind:src="image"/>
</div>
<div class="product-info">
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.min.js"></script>
<script type="text/javascript" src="main.js"></script>
This is main.js code
var app = new Vue({
el: '#app',
data: {
product: 'Socks'
image : "./img/1.png"
}
})
var app = new Vue({
el: '#app',
data: {
product: 'Socks',
image : "./img/1.png"
}
})
You are missing a comma after the product ppty -- 'Socks'
You can check the fiddle here.
https://jsfiddle.net/p0dynL8o/

Conditional a href in Vuejs

I am rendering a list of store titles in VueJS, some of them have a url property, some of them don't. If the title has a url, I want to add a a href property:
<div v-for="(store, index) in stores">
<span v-if="store.link"><a :href="store.link" target="_blank">{{ store.title }}</a></span>
<span v-else="store.link">{{ store.title }}</span>
</div>
This works, but the code looks duplicated. Is there anyway to simplify the code further?
you can use component tag:
var app = new Vue({
el: '#app',
data () {
return {
stores: [
{title:'product1',link:'/products/222'},
{title:'product2'},
{title:'product3',link:'/products/333'},
{title:'product4'}
]
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<div v-for="(store, index) in stores">
<component :is="store.link?'a':'span'" :href="store.link || ''" target="_blank">{{store.title}}
</component>
</div>
</div>
I'd remove the first span element, as it's not necessary. Also, the v-else does not need the conditional statement (it's not v-else-if):
new Vue({
el: '#app',
data: {
stores: [
{ link: 'foo', title: 'foo-text' },
{ title: 'bar-text' }
]
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div v-for="(store, index) in stores" :key="index">
<a v-if="store.link" :href="store.link" target="_blank">{{ store.title }}</a>
<span v-else>{{ store.title }}</span>
</div>
</div>
You can use dynamic arguments in vue3
https://v3.vuejs.org/guide/template-syntax.html#dynamic-arguments
<a v-bind:[attributeName]="url"> ... </a>
or binding an object of attributes
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

How to render v-for from particular index

I want to loop in v-for from suppose from number 5 to 10 .
The loop want to be started at 5 and end at 10.
I have tried this
<div v-for="n in 10" v-if="n>=5"></div>
But I want more effective way of doing the loop . Does anyone knows how to do so that loop starts at 5 ?
Its possible for your example:
<div v-for="i in range(5, 10)">
... some code here
</div>
and mount range function:
var app = new Vue({
el: '#app',
methods:{
range : function (start, end) {
return Array(end - start + 1).fill().map((_, idx) => start + idx)
}
}
});
and sample in jsfidle.
If want know more than this github issue can help you.
Also try this simple approach:
new Vue({
el: '#test',
data: {
items: [
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10'
]
},
methods: {
sliceItems: function (start, end) {
return this.items.slice(start, end);
}
}
})
<script src="https://unpkg.com/vue#2.4.2/dist/vue.min.js"></script>
<div id="test">
<ul>
<li v-for="(item, index) in sliceItems(5,10)" >{{ item }}</li>
</ul>
</div>
Another simple alternative is to just use basic +/-:
new Vue({
el: '#app',
data: {
start: 5,
end: 10
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<ul>
<li v-for="i in end-start" >{{ i+start }}</li>
</ul>
</div>
If you really need to use {{ i }} a lot of times and is bothered by adding start, you can use a little trick:
new Vue({
el: '#app',
data: {
start: 5,
end: 10
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<ul>
<template v-for="curr in end-start" >
<li v-for="i in [curr+start]">
{{ i }}{{ i }}{{ i }}{{ i }}{{ i }}{{ i }}{{ i }}{{ i }}{{ i }}
</li>
</template>
</ul>
</div>

Any easier way to access nested object properties in Vue template?

It's convenient to group data into nested object properties. By doing this, we don't have to collect properties from the data field into an entity for later use. As in the following example,
var demo = new Vue({
el: '#demo',
data: {
level1: {
level2: {
level3_1: 'Hello',
level3_2: 'world'
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="demo">
<div class="person">
<h3>{{ level1.level2.level3_1 }}</h3>
<p>{{ level1.level2.level3_2 }}</p>
</div>
</div>
However, it's really overkill having to type the "level1.level2" prefix in order to get to the level3_x field. It'll be very cumbersome if there're loads of level3 fields.
I wonder if there is any way that I can save the work for typing level1.level2 over and over again. Does the template have any syntax so that some section is under the scope of "level1.level2"? Does Vue provide any support so that in this case the prefix "level1.level2" is assumed?
There are a couple of options.
1. Use v-for
Everything inside the v-for block is scoped to the level that you're iterating over. Do it like this:
var demo = new Vue({
el: '#demo',
data: {
level1: {
level2: {
level3_1: 'Hello',
level3_2: 'world'
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="demo">
<div class="person">
<template v-for="(l2prop, l2propName) in level1">
<h3>{{ l2prop.level3_1 }}</h3>
<p>{{ l2prop.level3_2 }}</p>
</template>
</div>
</div>
2. Use a component
Components get a subset of their parent's data, so they're automatically scoped. Do it like this:
Vue.component( "person", {
props: ['data'],
template: '<div class="person"><h3>{{ data.level3_1 }}</h3><p>{{ data.level3_2 }}</p></div>'
});
var demo = new Vue({
el: '#demo',
data: {
level1: {
level2: {
level3_1: 'Hello',
level3_2: 'world'
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="demo">
<person v-bind:data="level1.level2"></person>
</div>
The example of #jason-smith is almost right. v-for is used for arrays or lists. To make it work is necessary to put your object in list.
Following his example the better approach would be
var demo = new Vue({
el: '#demo',
data: {
level1: {
level2: {
level3_1: 'Level 3_1',
level3_2: 'Level 3_2'
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div class="person">
<template v-for="level2Obj in [level1.level2]">
<h3>{{ level2Obj.level3_1 }}</h3>
<p>{{ level2Obj.level3_2 }}</p>
</template>
</div>
</div>
There are serval ways:
Use a method that gets the same level
methods:{
getLvl3: function(nr){
return this["level"+nr]["level"+nr]["level3_"+nr];
}
{{ getLvl3(1) }}
Iterate over with v-for v-for docu
example:
<div id="demo">
<div class="person">
<template v-for="(lvl2, key) in level1">
<template v-for="(lvl3, key) in lvl2">
<h3 v-if="key === 'level3_1'>{{ lvl3 }}</h3>
<p v-if="key === 'level3_2'">{{ lvl3 }}</p>
</template>
</template>
</div>
</div>
bind to variable that is defined outside of vue:
var nested = { level1: { level2: { level3_1: 'Hello', level3_2: 'world' }}
and inside of vue component or instance:
data:{
level2: nested.level1.level2,
}
<div id="demo">
<div class="person">
<h3>{{ level2.level3_1 }}</h3>
<p>{{ level2.level3_2 }}</p>
</div>
</div>