Reputation: 1073
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?
Upvotes: 3
Views: 13967
Reputation: 1660
There are serval ways:
Use a method that gets the same level
methods:{ getLvl3: function(nr){ return this["level"+nr]["level"+nr]["level3_"+nr]; }
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>
Upvotes: 0
Reputation: 1372
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>
Upvotes: 0
Reputation: 1209
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>
Upvotes: 6