vue.js - 为什么 nuxt-link 与 Bootstrap-vue 一起使用时会刷新页面?
问题描述
我正在使用 nuxt 和 bootstrap 构建自定义悬停下拉菜单以进行导航。我遇到的问题是我的导航子菜单 NuxtLinks 正在刷新整个页面,而不是平滑地更改我的 Nuxt 块中的应用程序内容。导航栏在 default.vue 布局中动态生成,并使用一个 b-dropdown-hover 组件,其中 NuxtLink 围绕该内容进行包装。为什么页面会对这些链接/锚点进行完全刷新,但我的 b-navbar-brand 图像却可以平滑过渡?对不起,我对 Nuxt 很陌生。这段视频@ ~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>
解决方案
这里有很多不相关的代码。我花时间正确格式化它。下次请自己努力(仅格式化和输入有趣的位)。
此外,视频本身实际上给出了如何解决问题的答案。该视频正在讨论标签之间a
的差异。nuxt-link
这与Bootstrap 的 Vue 文档的这一部分有关,您可以在其中看到
[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 创建项目,玩得开心!
推荐阅读
- java - 正确的设计模式和技术以相互映射功能
- pandas - 如何根据多个条件填充
- swift - 如何在等距网格周围设置边界?
- javascript - 如何从另一个模态调用一个模态?
- c# - 尝试失败后使用 Polly ExecuteAsync 时是否可以更改客户端的 BaseAddress 或客户端?
- aws-lambda - 将 aws lambda 与 java 和 Spring Cloud Functions 用于其他语言是一个好主意吗?
- java - 在 java eclipse 内存分析器中:获取堆转储对话框显示没有要获取的 PID
- reactjs - 使用 Sass (React) 在 Materialise 中更改主题颜色
- sql - 图像中的十六进制字节数组用空格填充,并且 - 在 INSERT 到表 postgresql 之后
- python - 是否可以不让用户关闭 Tkinter 窗口?