Nuxt-Link verwendet Bootstrap-vue, um das Seitenproblem zu aktualisieren
P粉512729862
P粉512729862 2023-12-07 08:58:02
0
1
724

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粉512729862
P粉512729862

Antworte allen(1)
P粉569205478

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

此外,视频本身已经给出了如何解决该问题的答案。该视频正在讨论 anuxt-link 标签之间的区别。

这与 Bootstrap 的这一部分相关Vue 文档,您可以在其中看到

所以,你应该使用这样的东西


我还发现您的代码与视频有很大不同。您不应该使用 querySelector,您也不必导入 Nuxt 组件,并且您会遇到几个 ESlint 警告/错误。

我确实建议尝试专注于学习的单个部分,而不是混合所有内容。想要更进一步是可以的,但要小心,当你学习很多新概念(Vue/Nuxt)时,不要迷失在太多的抽象中。


顺便说一句,如果你想继续学习Nuxt,你可以查看这个:https://masteringnuxt.com/ (由 Nuxt 大使和 Vue 生态系统中的其他知名人士创建)

享受使用 Nuxt 创建项目的乐趣!

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage