为啥 nuxt-link 与 Bootstrap-vue 一起使用时会刷新页面?
Posted
技术标签:
【中文标题】为啥 nuxt-link 与 Bootstrap-vue 一起使用时会刷新页面?【英文标题】:Why is nuxt-link refreshing the page when used with Bootstrap-vue?为什么 nuxt-link 与 Bootstrap-vue 一起使用时会刷新页面? 【发布时间】:2021-10-19 17:19:22 【问题描述】:我正在使用 nuxt 和 bootstrap 构建自定义悬停下拉菜单以进行导航。我遇到的问题是我的导航子菜单 NuxtLinks 正在刷新整个页面,而不是平滑地更改我的 Nuxt 块中的应用程序内容。导航栏在 default.vue 布局中动态生成,并使用一个 b-dropdown-hover 组件,其中 NuxtLink 围绕该内容进行包装。为什么页面会为这些链接/锚点进行完全刷新,但我的 b-navbar-brand 图像却可以平滑过渡?抱歉,我对 Nuxt 很陌生。 This video @ ~1:35:00 展示了我正在尝试做的事情。
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>
【问题讨论】:
【参考方案1】:这里有很多不相关的代码。我花时间正确格式化它。下次请自己努力(仅格式化和输入有趣的位)。
此外,有关如何解决此问题的答案实际上已在视频中给出。该视频正在讨论a
和nuxt-link
标签之间的区别。
这与Bootstrap's Vue documentation 的这一部分有关,您可以在其中看到
[to] prop:表示链接的目标路由。点击时,to prop 的值会在内部传递给
router.push()
,因此该值可以是字符串也可以是Location 描述符对象
所以,你应该使用这样的东西
<template>
<b-dropdown>
<template #button-content>
Custom <strong>Content</strong> with <em>html</em> via Slot
</template>
<b-dropdown-item to="/test">Go to test page via Vue-router</b-dropdown-item>
</b-dropdown>
</template>
我还看到您的代码与视频有很大不同。你不应该使用querySelector
,你也不必导入 Nuxt 组件并且你有几个 ESlint 警告/错误。
我确实建议您尝试专注于学习的单个部分,而不是混合所有部分。想走得更远一点很好,但要注意不要在学习很多新概念(Vue/Nuxt)时迷失太多抽象。
附带说明,如果您想继续学习 Nuxt,可以查看:https://masteringnuxt.com/(由 Nuxt 大使和 Vue 生态系统中的其他知名人士创建)
享受使用 Nuxt 创建项目的乐趣!
【讨论】:
感谢您的回答!通过将我的导航 seutp 数组移动到 vuex 状态而不是 data() 中,我能够得到我想要的结果。这些链接现在被视为 Nuxt 链接而不是标签。以上是关于为啥 nuxt-link 与 Bootstrap-vue 一起使用时会刷新页面?的主要内容,如果未能解决你的问题,请参考以下文章