I am trying to create nested list with more than three levels of nesting. When I put children object of items inside child item in v-list it doesn't display anything.
Is is even possible to create such nested list in vuetify? If not, what solution could be to this problem?
<div>
<v-list v-for="(powerPlant, i) in powerPlants" :key="i">
<v-list-group
prepend-icon="fas fa-bolt"
value=""
>
<v-list-tile slot="activator">
<v-list-tile-title>{{powerPlant.name}}</v-list-tile-title>
</v-list-tile>
<v-list-group
no-action
sub-group
value="true"
v-for="(generator, i) in generators" :key="i"
>
<v-list-tile slot="activator">
<v-list-tile-title>{{generator.name}}</v-list-tile-title>
</v-list-tile>
<v-list-tile
v-for="(option, i) in options"
:key="i"
>
<v-list-tile-title v-text="option[0]"></v-list-tile-title>
<v-list-tile-action>
<v-icon v-text="option[1]"></v-icon>
</v-list-tile-action>
</v-list-tile>
</v-list-group>
</v-list-group>
</v-list>
</div>
If there is another way to make big nested list using Vue.js without using jQuery I would like to learn to.
Sorry for not explain well. In this way a have posted a can reach 3 levels of list, but i cant go further like four or five levels.
I solved this by nesting v-list like this:
<v-list>
<v-list-group v-for='node in nodes' v-model='node.active'>
<v-list-tile slot='activator' #click=''>
<v-list-tile-title>{{node.text}}</v-list-tile-title>
</v-list-tile>
<v-list class='py-0 pl-1'>
<v-list-group v-for='child in node.children' v-model='child.active'>
<v-list-tile slot='activator' #click=''>
<v-list-tile-title>{{child.text}}</v-list-tile-title>
</v-list-tile>
<v-list class='py-0 pl-2' v-for='grandchild in child.children'>
<v-list-tile>
<v-list-tile-title>{{grandchild.text}}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-list-group>
</v-list>
</v-list-group>
</v-list>
This can go arbitrarily deep. In fact, I needed an infinitely nesting list so I created this simple recursive component:
<template>
<v-list>
<template v-for='node in nodes'>
<v-list-group v-if='node.children && node.children.length' v-model='node.active'>
<v-list-tile #click='' slot='activator'>
<v-list-tile-title>{{node.text}}</v-list-tile-title>
</v-list-tile>
<node-list class='py-0 pl-3' :nodes='node.children'/>
</v-list-group>
<v-list-tile #click='' v-else>
<v-list-tile-title>{{node.text}}</v-list-tile-title>
</v-list-tile>
</template>
</v-list>
</template>
<script>
export default {
name: 'node-list',
props: ['nodes'],
}
</script>
Related
I'm trying to replicate a menu example from Vuetify but this is not working as easier as it's shown. Main items of the menu are displayed but I can't open the slots to show the sub items.
The example code is at: https://vuetifyjs.com/en/components/lists/#slots
<div>
<v-toolbar color="blue">
<v-app-bar-nav-icon></v-app-bar-nav-icon>
<v-toolbar-title>Topics</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon>
<v-icon>mdi-dots-vertical</v-icon>
</v-btn>
</v-toolbar>
<v-list>
<v-list-group v-for="item in items" :key="item.title" v-model="item.active" no-action :prepend-icon="item.action">
<template v-slot:activator>
<v-list-item link>
<v-list-item-title v-text="item.title"></v-list-item-title>
</v-list-item>
</template>
<!--v-list-item-content -->
<v-list-item v-for="child in item.items" :key="child.title">
<v-list-item-title v-text="child.title"></v-list-item-title>
</v-list-item>
<!--/!--v-list-item-content -->
</v-list-group>
</v-list>
</div>
</template> ```
Vuetify for vue3 uses activator prop for their lists. For Example :
<v-list-group value="Admin">
<template v-slot:activator="{ props }">
<v-list-item
v-bind="props"
title="Admin"
></v-list-item>
</template>
<v-list-item
v-for="([title, icon], i) in admins"
:key="i"
:title="title"
:prepend-icon="icon"
:value="title"
></v-list-item>
</v-list-group>
Here is a link for reference:
https://next.vuetifyjs.com/en/components/lists/
Here is a link for working sample:
https://codepen.io/pen?&editors=101
"Menus can be placed within almost any component" says in the Vuetify's docs
but I'm trying to place it into a List Item, and it doesn't work:
<template>
<v-row align="center" justify="center" cols="12">
<v-col cols="12" sm="10" md="6" lg="8">
<v-list three-line>
<v-subheader>Saved Addresses</v-subheader>
<template v-for="address in userAddresses">
<v-menu bottom left :id="address.id">
<template v-slot:activator="{ on, attrs }">
<v-list-item :key="address.id" #click="">
<v-list-item-avatar>
<v-icon>home</v-icon>
</v-list-item-avatar>
<v-list-item-content>
<v-list-item-title>{{address.adress}}
</v-list-item-title>
<v-list-item-subtitle>{{address.country_id }}, {{address.state_id}},
{{address.city_id}}
<strong>| {{address.postal_code}}</strong></v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</template>
<v-list>
<v-list-item>
<v-list-item-title>Edit</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</template>
</v-list>
</v-col>
</v-row>
</template>
When I click any list item it doesn't show the dropdown menu, I tried different combinations of wrapping the menu template, but same result, or even error.
I'm building a navigation inside a permanent drawer using the v-list and I following the guide I completed it.
When the drawer is collapsed it display just the icons, on hover it expand showing the name of the navigation items as well.
A few items are groups and if I click on them I can see sub items.
The issue comes when I wish to force to collapse the active sub items when my drawer collapse.
Here is the code:
<v-navigation-drawer
v-model="mainSidebarDrawer"
:mini-variant.sync="mini"
fixed
expand-on-hover
permanent
>
<v-list>
<template v-for="(n, i) in nav">
<v-list-item v-if="n.to" :key="`${i}-a`" :to="n.to" link>
<v-list-item-icon>
<v-icon small>{{ n.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ n.label }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-group
v-if="n.subItems"
:key="`${i}-b`"
:prepend-icon="`${n.icon} fa-em`"
:value="subItemsValue" // this looks always false
append-icon="fas fa-chevron-down fa-sm"
>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title>{{ n.label }}</v-list-item-title>
</v-list-item-content>
</template>
<v-list-item
v-for="(s, y) in n.subItems"
:key="y"
:to="s.to"
link
class="pl-8"
>
<v-list-item-icon>
<v-icon small>{{ s.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ s.label }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-group>
</template>
</v-list>
</v-navigation-drawer>
The Vue code has:
data() {
return {
mainSidebarDrawer: true,
mini: true,
subItemsValue: false
}
}
So, just to recap:
drawer is collapsed showing just the icons of my navigation list
on hover it expand, icon and text are visible
clicking on a list group it expand the sub-items
moving the mouse away from the drawer cause it to collapse like point 1
list group remain expanded. I wish to collapse it back
What I tried so far is to listen at the mini property and doing this:
<v-navigation-drawer
...
#update:mini-variant="collapseSubItems"
</v-navigation-drawer>
methods: {
collapseSubItems() {
if (this.mini) {
this.subItemsValue = false
}
}
}
Unfortunately the subItemsValue never change. I tried also to move it in the v-model.
How can achieve my result? Thanks
I think instead of using a single var like subItemsValue, use an "active" state var on each nav item. Then use the transitionend event to set the open nav item to back to active: false...
<v-navigation-drawer
v-model="mainSidebarDrawer"
permanent
expand-on-hover
#transitionend="collapseSubItems"
>
<v-list>
<template v-for="(n, i) in nav">
<v-list-item v-if="n.to" :key="`${i}-a`" :to="n.to" link>
<v-list-item-icon>
<v-icon small>{{ n.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ n.label }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-group
v-if="n.subItems"
:key="`${i}-b`"
:prepend-icon="`${n.icon} fa-em`"
v-model="n.active"
append-icon="fas fa-chevron-down fa-sm"
>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title>{{ n.label }}</v-list-item-title>
</v-list-item-content>
</template>
<v-list-item
v-for="(s, y) in n.subItems"
:key="y"
:to="s.to"
link
class="pl-8"
>
<v-list-item-icon>
<v-icon small>{{ s.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ s.label }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-group>
</template>
</v-list>
</v-navigation-drawer>
collapseSubItems() {
this.nav.map((item)=>item.active=false)
},
Demo: https://codeply.com/p/qzrKTPSzrB
I'm new to Vuetify and Vue in general, and can not seem to figure this one out. I have a need to create multiple sub-groups, from which only one option can be selected under the "parent" list.
So for example I have an array of cats:
options:["Crookshanks", "Garfield", "Leeroy"]
which are split over 2 sub-groups (pseudo code below)
subgroup 1
Crookshanks
Garfield
subgroup 2
Leeroy
From my end, I've achieved extracting the text content of the selected item which replaces itself if another option is clicked (not pretty, but works).
Now I'd like to create some sort of visual changes (highlight or a check mark) so that it would be clear which item is selected. It should be a toggle-effect on one selected item at a time only, so that if any other option is selected, the effect on the previous option clears. Setting a manual active class unfortunately did not work (I suspect it's not available for sub-groups?):
<v-list-item
active-class="selectedCat">
Here is a Codepen for playing around. Would really appreciate some help!
You must to use the component v-list-item-group for highlight the selected element. Try something like this:
<template>
<div id="app">
<div>
fictionalSelected = {{ fictionalSelected }}
</div>
<div>
realSelected = {{ realSelected }}
</div>
<v-app id="inspire">
<v-card class="ma-1" width="700">
<v-list>
<v-list-group prepend-icon="pets">
<template v-slot:activator>
<v-list-item-title>CATS</v-list-item-title>
</template>
<v-list-group no-action sub-group>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title>Fictional</v-list-item-title>
</v-list-item-content>
</template>
<v-list-item-group v-model="fictionalSelected" #change="fictionalChanged">
<v-list-item v-for="cat in fictionals">
<v-list-item-title>{{ cat }}</v-list-item-title>
</v-list-item>
</v-list-item-group>
</v-list-group>
<v-list-group sub-group no-action>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title>Real</v-list-item-title>
</v-list-item-content>
</template>
<v-list-item-group v-model="realSelected" #change="realChanged">
<v-list-item v-for="cat in reals">
<v-list-item-title>{{ cat }}</v-list-item-title>
</v-list-item>
</v-list-item-group>
</v-list-group>
</v-list-group>
</v-list>
</v-card>
</v-app>
</div>
</template>
<script>
export default {
name: 'app',
data: () => ({
fictionals: ['Crookshanks', 'Garfield'],
fictionalSelected: null,
reals: ['Leeroy'],
realSelected: null,
}),
methods: {
fictionalChanged() {
console.log('fictionalChanged');
this.realSelected = null;
},
realChanged() {
console.log('realChanged');
this.fictionalSelected = null;
},
},
};
</script>
I'm using the VuetifyJS dropdown menu component and I need to get it to the same width of the other button in my attached example. Unfortunately the block settings don't work.
CodePen example of the issue: https://codepen.io/anon/pen/djvyVw?&editors=101
<div id="app">
<v-app id="inspire">
<v-card>
<v-flex xs10 offset-xs1>
<v-btn block round depressed dark large color="green darken-4">
<v-icon large>info</v-icon>
</v-btn>
<v-menu offset-y>
<v-btn block outline round depressed dark large color="yellow darken-3" slot="activator">
<v-icon>info</v-icon>Learn More</v-btn>
<v-list>
<v-list-tile v-for="(item, index) in items" :key="index" #click="" :class="item.color">
<v-list-tile-title>{{ item.title }}</v-list-tile-title>
</v-list-tile>
</v-list>
</v-menu>
</v-flex>
</v-card>
</v-app>
</div>
How to get it to full width like the other button?
Simply give v-menu the full-width attribute:
<v-menu offset-y full-width>
...
</v-menu>