簡體   English   中英

如何在沒有路由的情況下使 vuejs 導航欄鏈接在點擊時處於活動狀態

[英]How to make vuejs navbar link active on click without route

我有一個 vue 引導導航欄。 除了一個之外,所有導航項目都有一條路線。 沒有(聯系)的那個會在點擊時啟動一個模式。 When an item is selected I want the item to be white.

我這樣做,它適用於具有相應路線的項目:

:active='$route.name ==""'

導航欄

<ul class="navbar-nav">
    <li class="nav-item">
        <router-link class="nav-link" :to="{
                      path: '/',
                      hash: 'home',
                    }" :active='$route.name =="home"'>Home</router-link>
    </li>
    <li class="nav-item">
        <router-link to="/About" :active='$route.name =="about"' class="nav-link">About</router-link>
    </li>
    <li class="nav-item">
        <a class="nav-link" v-b-modal.modal-contact>Contact</a>
    </li>
</ul>

如何讓聯系人項目在點擊時處於活動狀態?

您似乎需要一種機制來在兩個或多個組件之間共享數據。 在您的情況下,導航組件和模式(或打開模式的組件,或模式中包含的某些組件 - 它可以通過多種方式完成)。

但是,無論如何,您必須將模態的 state 存儲到外部存儲器中。 它可以是一個簡單的常量,可以在任何你想從中讀取或寫入的地方導入。 這個存儲也應該被導入你的菜單並用於更新導航鏈接的:active屬性。

Vue 應用程序中商店的典型解決方案是 Vuex,但我不會在這里介紹它,我將提供一個更簡單的選項。

可以使用Vue.observable() 它會生成一個反應式 object,可以將其導入應用程序的任何位置。 每當其中一個組件修改了其中一個存儲成員(道具)時,讀取它的每個其他地方都會收到更改。 將其視為浮動data() (不包含在特定組件中,但可在您需要的任何地方導入)。 通常它是通過使用 store 屬性創建computed props 來消耗的,因此它將自動更新(就像在computed中使用組件自己的data()時一樣)。

在您的情況下, store.js (或.ts ,如果您使用打字稿)將如下所示:

import Vue from 'vue';

const store = Vue.observable({
  isModalOpened: false
});

export default store;

現在,根據您的模態框的外觀,有幾種方法可以將模態框當前打開的 state 鏈接到商店。 如果您的 modal 包含專用組件,您可以使用該特定組件的生命周期掛鈎來更新商店:

import store from './path-to/store'
//...
  mounted() {
    store.isModalOpened = true;
  },
  beforeDestroy() {
    store.isModalOpened = false;
  }

如果您的模態不包含在模態打開時安裝並在關閉時銷毀的組件,則必須從打開模態(通常是模態容器)的位置設置store.isModalOpened並將其設置為關閉從您關閉它的位置(通常是模態組件)。 如果您需要有關特定案例的幫助,則必須提供可運行的最小可重現示例

An alternative method of linking the modal's state to the store would be using BootstrapVue's modal v-model property , which is quite convenient in your case: instead of trying to set the store prop according to the modal's state, you can set the modal's model (狀態)根據商店屬性。 當您將 store 屬性更改為true時,模式打開,當您將其設置為false時,它關閉。
為了還允許模態更新存儲(當從存儲外部修改 state 時),您可以使用計算的 setter 這是一個例子:

import store from './path-to/store'
//...
  computed: {
    isModalOpened: {
      get: () => store.isModalOpened,
      set: value => { store.isModalOpened = value; }
    }
  }

//template:
  <b-modal v-model="isModalOpened">

現在你的模態和商店是同步的。 剩下要做的就是在導航組件中導入商店,並在打開模式時使用它來設置活動 class。

import store from './path-to/store';

//...
  computed: {
    store: () => store
    // or, if you don't want to expose the entire store:
    isModalOpened: () => store.isModalOpened
    // but then you'd need to use `:active="isModalOpened"` in template.
  }

<template>中:

<li class="nav-item">
  <a class="nav-link"
     :active="store.isModalOpened"
     v-b-modal.modal-contact>Contact</a>
</li>

我遇到了和你一樣的問題,就這樣解決了。

首先,您定義一個將使用this.$routename屬性的方法

export default {
  name: 'App',
  methods: {
    getActiveNavLink(name) {
      //This is for the navbar classes, you can modify them as
      //as you need. (This will be assigned every-time we call this
      //function).
      let classString = "nav-item nav-link "
    
      //We compare the given name with the route current name.
      if (this.$route.name === name) {
        //If it is true, we append to the class string the "active" value
        classString += "active"
      }
      //Return the class string.
      return classString;
    }
  }
}

然后在你的導航欄中你做這樣的事情

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container-fluid">
    <a class="navbar-brand" href="#">The navegation bar</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
      <div class="navbar-nav">
        <router-link 
          :to="{ name: 'home'}"
          :class="getActiveNavLink('home')" >
          Home
        </router-link>
        <router-link
          :to="{ name: 'secondRoute'}"
          :class="getActiveNavLink('secondRoute')"><!--class="nav-item nav-link">-->
          To the second route!
        </router-link> 
        <router-link :to=...>
          ...
        </router-link> 
      </div>
    </div>
  </div>
</nav>

這樣,每次您調用getActiveNavLink時,您都會傳遞要比較的路由名稱,如果路由名稱與您的$route.name相同,您將獲得一個活動導航欄元素,另外,不要擔心路由器-鏈接類被覆蓋,它們不是,我們添加的類是附加的,而不是覆蓋的。

您可以使用router.push() 當您打開模態時,推送到該路徑,當您離開模態時,推送到上一個路徑。

https://router.vuejs.org/guide/essentials/navigation.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM