Discussion icon indicating copy to clipboard operation
Discussion copied to clipboard

Creating a nested list using v-repeat and $value

Open Neru opened this issue 10 years ago • 10 comments

Hi, I'm fairly new to Vue.js.

I'd like to create a nested list:

<ul id="menu">
    <li>Favourite Songs
        <ul>
            <li>2014</li>
            <li>2013</li>
        </ul>
    </li>
    <li>Favourite Genres
        <ul>
            <li>Pop</li>
            <li>Rock</li>
            <li>Hip Hop</li>
        </ul>
    </li>
</ul>

from this model:

var playlists =  {
    "Favourite Songs": {
        "2014": [],
        "2013": []
    },
    "Favourite Genres": {
        "Pop": [],
        "Rock": [],
        "Hip Hop": []
    }
}

I tried:

<ul id="menu">
    <li v-repeat="playlist: playlists">{{playlist.$key}}
        <ul>
            <li v-repeat="subcategory: {{playlist.$value}}">
                {{subcategory.$key}}
            </li>
        </ul>
    </li>
</ul>

with

new Vue({
    el: '#menu',
    data: {
        "playlists": playlists
    }
})

but it did not work. Is it actually possible or is there another way to achieve this?

Here is my playground: http://jsfiddle.net/8WqxC/

Thank you for your help!

Neru avatar Jun 19 '14 19:06 Neru

Here's a version that works. It seems using identifier with objects causes problems...

Also, when you are iterating over an object of objects, those objects are used directly as the child vm's root $data. In comparison, $value is only available for primitive values.

Basically, v-repeat doesn't play too well when doing nested loops of objects. If you have control over your data structure it might be better to use Arrays where appropriate.

yyx990803 avatar Jun 19 '14 22:06 yyx990803

Thanks. This solves the issue. It might worth adding the example to the "Displaying a List" guide on the Vue.js website.

Neru avatar Jun 22 '14 15:06 Neru

this is golden! Thanks

peterfoeng avatar Jan 30 '15 12:01 peterfoeng

An updated sample: http://jsfiddle.net/8WqxC/2/

On this data:

var playlists =  {
    "Favourite Songs": {
        "2014": ['song a', 'song b'],
        "2013": ['song c', 'song d', 'song e']
    },
    "Favourite Genres": {
        "Pop": ['song a'],
        "Rock": ['song b'],
        "Hip Hop": ['song c', 'song d', 'song e']
    }
}

With this markup:

<ul id="menu">
    <li v-repeat="playlist : playlists">
        {{$key}}
        <ul>
            <li v-repeat="sublist : playlist">
                {{$key}}
                <ul>
                    <li v-repeat="sublist">
                        {{$value}}
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

tiffon avatar Feb 20 '15 01:02 tiffon

@tiffon Thanks a lot :+1:

fer-ri avatar Oct 16 '15 09:10 fer-ri

Just started using vue-js, and I wonder if this method is deprecated in favor of v-for? Is this how you should do it in 1.0?

http://jsfiddle.net/z7mrmx1a/

mattiasottosson avatar Mar 28 '16 23:03 mattiasottosson

@mattiasottosson yes, v-repeat is deprecated in favor of v-for. There's also syntax for manually specifying key: v-for="(key, value) in object" and v-for="(index, value) in list".

We also don't use vuejs/Discussion anymore. You can find help on the forum or gitter chat.

simplesmiler avatar Mar 31 '16 07:03 simplesmiler

@simplesmiler isn't it actually v-for="(value, key) in object and v-for="(value, index) in list" ? That is to say, isn't the value the first parameter? (counterintuitive though it is)

https://vuejs.org/v2/api/#v-for

DoDSoftware avatar Jan 14 '17 17:01 DoDSoftware

@DelightedD0D please note the date, this was before 2.0.

simplesmiler avatar Jan 14 '17 17:01 simplesmiler

@simplesmiler fair enough :)

DoDSoftware avatar Jan 14 '17 17:01 DoDSoftware