Heim > Fragen und Antworten > Hauptteil
Ich verwende Nuxt und Bootstrap, um ein benutzerdefiniertes Hover-Dropdown-Menü für die Navigation zu erstellen. Das Problem, das ich habe, ist, dass die NuxtLinks meines Navigationsuntermenüs die gesamte Seite aktualisieren, anstatt den Anwendungsinhalt innerhalb des Nuxt-Blocks reibungslos zu ändern. Die Navigationsleiste wird dynamisch im default.vue-Layout generiert und verwendet die b-dropdown-hover-Komponente mit einem NuxtLink, der den Inhalt umschließt. Warum wird die Seite für diese Links/Anker vollständig aktualisiert, mein b-navbar-brand-Bild wechselt jedoch reibungslos? Entschuldigung, ich bin neu bei Nuxt. Dieses Video bei ~1:35:00 zeigt, was ich versuche.
components/BDropdownHoverRight.vue
<template> <nuxt-link :to="aTo"> <div class="ddr-top" @mouseover="onOver1($event.target)" @mouseleave="onLeave1($event.target)"> <b-dropdown ref="dropdown_ddr" :text="cText" class="m-md-2 ddr"> <slot></slot> </b-dropdown> </div> </nuxt-link> </template> <script> export default { name: 'BDropdownHoverRight', props: { cText: { type: String, }, aTo: { type: String, }, }, methods: { onOver1(t) { if (t.nodeName === 'DIV') { console.log(t) console.log(t.nodeName) let num_child_nodes = 0 try { if (t.querySelectorAll(':scope > ul')[0].getElementsByTagName('div').length >= 0) { num_child_nodes = t.querySelectorAll(':scope > ul')[0].getElementsByTagName('div').length } } catch (e) { if (t.querySelectorAll(':scope > div > ul')[0].getElementsByTagName('div').length >= 0) { num_child_nodes = t.querySelectorAll(':scope > div > ul')[0].getElementsByTagName('div').length } } if (num_child_nodes > 0) { try { t.querySelectorAll(':scope > div > ul')[0].style.display = 'block' } catch (e) { try { t.querySelectorAll(':scope > ul')[0].style.display = 'block' } catch (e) {} } } } }, onLeave1(t) { try { t.querySelectorAll(':scope > div > ul')[0].style.display = 'none' } catch (e) { try { t.querySelectorAll(':scope > ul')[0].style.display = 'none' } catch (e) {} } }, }, } </script>
layouts/default.vue
<template> <div> <b-navbar id="top-nav-bar" toggleable="lg" type="light" sticky> <b-navbar-brand to="/"> <Rabbit id="tl-logo" /> </b-navbar-brand> <b-navbar-toggle target="nav-collapse"></b-navbar-toggle> <b-collapse id="nav-collapse" is-nav> <b-navbar-nav> <template v-for="dir in navtop_dd"> <b-dropdown-hover :key="dir.id" :c-text="dir.name" :a-to="dir.hasOwnProperty('ato') ? dir.ato : '/nolink'" > <template v-if="'submenus' in dir && dir.submenus.length > 0"> <template v-for="dir1 in dir.submenus"> <b-dropdown-hover-right :key="dir1.id" :c-text="dir1.name" :a-to="dir1.hasOwnProperty('ato') ? dir1.ato : '/nolink'" > <template v-if="'submenus' in dir1 && dir1.submenus.length > 0"> <template v-for="dir2 in dir1.submenus"> <b-dropdown-hover-right :key="dir2.id" :c-text="dir2.name" :a-to="dir2.hasOwnProperty('ato') ? dir2.ato : '/nolink'" > </b-dropdown-hover-right> </template> </template> </b-dropdown-hover-right> </template> </template> </b-dropdown-hover> </template> </b-navbar-nav> <!-- Right aligned nav items --> <b-navbar-nav class="ml-auto"> <b-nav-form> <b-form-input size="sm" class="mr-sm-2" placeholder="Search"></b-form-input> <b-button size="sm" class="my-2 my-sm-0" type="submit">Search</b-button> </b-nav-form> <b-nav-item-dropdown right> <!-- Using 'button-content' slot --> <template #button-content> <b-img src="../assets/imgs/account-circle.svg" style="height: 35px"> </b-img> <!-- <em>User</em> --> </template> <b-dropdown-item href="#">Profile</b-dropdown-item> <b-dropdown-item href="#">Sign Out</b-dropdown-item> </b-nav-item-dropdown> </b-navbar-nav> </b-collapse> </b-navbar> <b-container id="app-content"> <Nuxt /> </b-container> <div id="footer"> <div style="height: 100%; padding: 5px">© 2021</div> </div> </div> </template> <script> import BDropdownHover from '@/components/BDropdownHover' import BDropdownHoverRight from '@/components/BDropdownHoverRight' export default { components: { BDropdownHover, BDropdownHoverRight, }, data() { return { navtop_dd: [ { id: 1, name: 'Transactions', ato: '/transactions', submenus: [ { id: '1a', name: 'Sales Orders', ato: '/transactions/salesorders', submenus: [ { id: '1b', name: 'New', }, { id: '2b', name: 'List', }, ], }, { id: '2a', name: 'Item Fulfillments', ato: '/transactions/itemfulfillments', submenus: [ { id: '1b', name: 'New', }, { id: '2b', name: 'List', }, ], }, ], }, { id: 2, name: 'Inventory', }, { id: 3, name: 'Reports', }, { id: 4, name: 'Setup', }, { id: 5, name: 'Support', }, ], } }, mounted() { var x = document.querySelectorAll('.b-dropdown.navtop-dd') for (var i = 0; i < x.length; i++) { if (x[i].querySelectorAll(':scope > ul')[0].getElementsByTagName('div').length == 0) { var btn = x[i].querySelectorAll(':scope > .btn')[0] btn.classList += ' no-content-after' } } var x = document.querySelectorAll('.b-dropdown.ddr') for (var i = 0; i < x.length; i++) { if (x[i].querySelectorAll(':scope > ul')[0].getElementsByTagName('div').length == 0) { var btn = x[i].querySelectorAll(':scope > .btn')[0] btn.classList += ' no-content-after' } } }, } </script> <style> #top-nav-bar { border-bottom: 1px solid green; } #tl-logo { height: 40px; margin: 5px; } #footer { height: 40px; color: black; border-top: 1px solid green; margin: auto; text-align: center; display: flex; align-items: center; justify-content: space-around; } .navtop-dd button { background: none !important; color: #6c757d !important; border: none !important; } #app-content { margin: 20px auto; } .ddr > button::after { display: inline-block; margin-left: 0.555em; right: 0px; content: ""; border-top: 0.25em solid transparent; border-right: 0.3em solid transparent; border-bottom: 0.25em solid transparent; border-left: 0.35em solid; vertical-align: 0.075em; } .b-dropdown { width: 100%; } .ddr > button { text-align: left; } .no-content-after::after { content: none !important; } .ddr > ul { top: -1.2rem; left: calc(100% - 0.5rem); } .dropdown-menu { min-width: 0 !important; } .dropdown-item { color: #6C757D; } .ddr-top:hover { background-color: #e4ffda; } a:hover { text-decoration: none !important; } </style>
P粉5692054782023-12-08 00:28:41
这里有很多不相关的代码。我花了时间正确格式化它。下次请自己努力(仅格式化和输入有趣的位)。
此外,视频本身已经给出了如何解决该问题的答案。该视频正在讨论 a
和 nuxt-link
标签之间的区别。
这与 Bootstrap 的这一部分相关Vue 文档,您可以在其中看到
所以,你应该使用这样的东西
Custom Content with HTML via Slot Go to test page via Vue-router
我还发现您的代码与视频有很大不同。您不应该使用 querySelector
,您也不必导入 Nuxt 组件,并且您会遇到几个 ESlint 警告/错误。
我确实建议尝试专注于学习的单个部分,而不是混合所有内容。想要更进一步是可以的,但要小心,当你学习很多新概念(Vue/Nuxt)时,不要迷失在太多的抽象中。
顺便说一句,如果你想继续学习Nuxt,你可以查看这个:https://masteringnuxt.com/ (由 Nuxt 大使和 Vue 生态系统中的其他知名人士创建)
享受使用 Nuxt 创建项目的乐趣!