为啥 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】:

这里有很多不相关的代码。我花时间正确格式化它。下次请自己努力(仅格式化和输入有趣的位)。

此外,有关如何解决此问题的答案实际上已在视频中给出。该视频正在讨论anuxt-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 一起使用时会刷新页面?的主要内容,如果未能解决你的问题,请参考以下文章

为啥导航栏不会在 Bootstrap 5 中与右侧对齐?

为啥 Bootstrap 网格布局优于 HTML 表格?

Nuxt:如何防止 nuxt-link 转到另一个页面?

UI-Bootstrap Carousel 不会与我的 Angular 应用程序合作。为啥?

为啥bootstrap.css无法引入

如何使用 NuxtJS <nuxt-link /> 创建后退按钮?