How to generate multi level menu using Vue.js, Quasar's QMenu component and Pug?
-
I have Vue.js application in which I use Quasar’s QMenu component and Pug templates.
I don’t have enough experience with Pug and suppose I’ve missed something.
It looks as following:
The code:
Catalog data:
mounted () { this.catalog = [ { title: 'Компрессоры', permalink: 'kompressory', hasChildren: true, cover: 'kk', subcatalog: [ { title: 'A1', permalink: 'a1', hasChildren: false, cover: 'aa1', }, { title: 'B1', permalink: 'b1', hasChildren: false, cover: 'bb1', }, ] }, { title: 'Ручной инструмент', permalink: 'ruchnoy-instrument', hasChildren: false, cover: 'rr', }, { title: 'Пневмоинструмент', permalink: 'pnevmoinstrument', hasChildren: false, cover: 'pp', }, { title: 'Специальный инструмент', permalink: 'spetsialnyy-instrument', hasChildren: false, cover: 'ss', }, { title: 'Оборудование для СТО', permalink: 'garazhnoe-oborudovanie', hasChildren: false, cover: 'oo', }, ] }
Main template:
<template lang="pug"> include ./pug_mixins/createMenu.pug .q-pa-md .q-gutter-md.row.items-center q-btn(color='primary' label='Click me') q-menu(v-model='showing') +createMenu(catalog) q-item(clickable) q-item-section Preferences q-item-section(side) q-icon(name='keyboard_arrow_right') q-menu(anchor='top end' self='top start') q-list q-item(v-for='n in 3' :key='n' dense clickable) q-item-section Submenu Label q-item-section(side) q-icon(name='keyboard_arrow_right') q-menu(auto-close anchor='top end' self='top start') q-list q-item(v-for='n in 3' :key='n' dense clickable) q-item-section 3rd level Label q-separator q-item(clickable v-close-popup) q-item-section Quit </template>
Pug mixin - createMenu.pug:
mixin createMenu(catalog) q-list(dense style='min-width: 100px') q-item( v-for="category in catalog" :key="category.permalink" href='#' clickable v-close-popup ) q-item-section {{ category.title }} q-item-section(side) q-icon(name='keyboard_arrow_right')(v-if="category.hasChildren")
The screenshots:
When I click “Компрессоры” nothing happens. But, when I click “Preferences” the sub menus open.
I suppose there is an issue with v-for in mixin. I’m not sure how to handle this. Should I use Pug’s:
each item in catalog if item.hasChildren === true
and if so - where to use it?
But, when I try to use - each item in catalog:
mixin createMenu(catalog) q-list(dense style='min-width: 100px') each item in catalog if item.hasChildren q-item(clickable) q-item-section {{ category.title }} q-item-section(side) q-icon(name='keyboard_arrow_right')
I’ve got an error:
Failed to compile. ./src/App.vue?vue&type=template&id=7ba5bd90&lang=pug& (./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"409580f7-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/pug-plain-loader!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=template&id=7ba5bd90&lang=pug&) Module build failed (from ./node_modules/pug-plain-loader/index.js): TypeError: Cannot read property 'length' of undefined at Object.eval (eval at wrap (D:\Test projects\vue_quasar\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:13:32) at Object.pug_interp [as createMenu] (eval at wrap (D:\Test projects\vue_quasar\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:30:4) at eval (eval at wrap (D:\Test projects\vue_quasar\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:39:25) at template (eval at wrap (D:\Test projects\vue_quasar\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:41:7) at Object.module.exports (D:\Test projects\vue_quasar\node_modules\pug-plain-loader\index.js:13:10)
Actually, I’m trying to write come recursive code that should generate all subitems. How to do it using Quasar and Pug in Vue.js application?