簡體   English   中英

如何使路由器鏈接與自定義鏈接組件一起使用?

[英]How to make router-link work with custom link component?

<base-link>組件

我有一個 Vue 組件<base-link> ,每次我想要一個 achor 時都會使用它。 它主要用於應用特定於鏈接的樣式,以便整個頁面上的所有鏈接看起來都一樣,而無需應用全局樣式。

使<router-link>使用<base-link>

使用<router-link>組件創建鏈接時,除非<router-link>使用我的<base-link>組件創建錨元素,否則我無法應用這些樣式( <base-link>樣式是作用域的)。

幸運的是<router-link>提供了tag屬性,這似乎正是這樣做的。 不幸的是,我無法讓它工作。 我有兩個問題:

  1. 我所有的組件都是在本地注冊的(我使用帶有 Webpack 的 ES6 模塊並在每次需要時在本地導入組件)。 <router-link>不知道<base-link>組件是什么並且無法渲染它。 有沒有辦法注入一個本地組件供<router-link>使用?

  2. 為了解決問題 #1,我認為全局聲明<base-link>組件就足夠了。 不幸的是,它仍然不起作用。 這次<base-link>組件被正確渲染,但仍然無法正常工作 - 不會對點擊事件做出反應。 在我看來,問題在於它的href屬性根本沒有設置。 有沒有辦法讓<router-link>正確設置它? (無需手動設置)

問題

如何解決問題 #1 和 #2? 我懷疑#1 可能是不可能的,但我希望至少#2 是。

代碼示例

是一支帶有下面代碼的筆,它說明了這兩個問題。

const router = new VueRouter({
  routes: [
    {
      path: "/",
      component: {
        template: '<p>Homepage template</p>'
      }
    },
    {
      path: "/subpage",
      component: {
        template: '<p>Subpage template</p>'
      }
    }
  ]
});

// Globally registered BaseLink.
Vue.component('BaseLinkGlobal', {
  props: {
    href: String
  },
  template: `
    <a
      :href="href"
      class="BaseLinkGlobal"
    >
      <slot />
    </a>
  `
})

const vue = new Vue({
  el: "#app",
  router,
  components: {
    // Locally registered BaseLink.
    BaseLinkLocal: {
      props: {
        href: String
      },
      template: `
        <a
          :href="href"
          class="BaseLinkLocal"
        >
          <slot />
        </a>
      `
    }
  },
  template: `
    <div>
      <!-- 2 router links. One uses locally registered BaseLink
        -- and the other one a globally registered one. -->
      <nav>
        <router-link
          to="/"
          tag="base-link-local"
        >
          Home
        </router-link>
        <router-link
          to="/subpage"
          tag="base-link-global"
        >
          Subpage
        </router-link>
      </nav>
      <router-view />
    </div>
  `
});

您可以創建一個基本鏈接組件,該組件可以根據a兼作普通標簽或<router-link>

//Base link

<template>
  <component :is="type" :class="{'base': type === 'a'}" v-bind="$attrs">
    <slot></slot>
  </component>
</template>

<script>
export default {
  props: {
    routerLink: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    type() {
      return this.routerLink ? 'router-link' : 'a'
    }
  }
}
</script>

<style scopex>
.base {
  border: 1px solid red;
}
</style>

用法

當您想將其用作普通鏈接時,請不要提供router-link道具,如下所示:

<base-link>This is a base a tag</base-link>

要將其用作router-link ,只需添加router-link道具和to道具:

<base-link router-link to="/">This is router-link</base-link>

關於base-link組件的說明:

  • 我們使用 vuejs 提供a component根據routerLink屬性的真實性來渲染標簽或router-link

  • 如果是普通鏈接,則添加.base類, a

  • 我們綁定$attrs ,它允許我們使組件更加透明,即允許我們使用hrefto等屬性,而無需將它們作為 props 傳遞。

     <base-link href="https://google.com">go to google</base-link>

您可以在這里查看有關$attrs用法的更多說明

這是為了解決問題 #2

全局組件不繼承路由器鏈接的事件監聽器。 您可以通過將v-on="$listeners"添加到全局組件來使其繼承。

// Globally registered BaseLink.
Vue.component('BaseLinkGlobal', {
  props: {
    href: String
  },
  template: `
    <a
      :href="href"
      class="BaseLinkGlobal"
      v-on="$listeners"
    >
      <slot />
    </a>
  `
})

添加后鏈接有效: https ://codepen.io/jacobgoh101/pen/YvqJxL?editors=0010

暫無
暫無

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

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