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>
這里有很多不相關(guān)的代碼。我花了時間正確格式化它。下次請自己努力(僅格式化和輸入有趣的位)。
此外,視頻本身已經(jīng)給出了如何解決該問題的答案。該視頻正在討論 a
和 nuxt-link
標(biāo)簽之間的區(qū)別。
這與 Bootstrap 的這一部分相關(guān)Vue 文檔,您可以在其中看到
所以,你應(yīng)該使用這樣的東西
Custom Content with HTML via Slot Go to test page via Vue-router
我還發(fā)現(xiàn)您的代碼與視頻有很大不同。您不應(yīng)該使用 querySelector
,您也不必導(dǎo)入 Nuxt 組件,并且您會遇到幾個 ESlint 警告/錯誤。
我確實建議嘗試專注于學(xué)習(xí)的單個部分,而不是混合所有內(nèi)容。想要更進一步是可以的,但要小心,當(dāng)你學(xué)習(xí)很多新概念(Vue/Nuxt)時,不要迷失在太多的抽象中。
順便說一句,如果你想繼續(xù)學(xué)習(xí)Nuxt,你可以查看這個:https://masteringnuxt.com/ (由 Nuxt 大使和 Vue 生態(tài)系統(tǒng)中的其他知名人士創(chuàng)建)
享受使用 Nuxt 創(chuàng)建項目的樂趣!