![](/img/trans.png)
[英]Custom Vue library component with <router-link>, how to synchronize router state?
[英]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
屬性,這似乎正是這樣做的。 不幸的是,我無法讓它工作。 我有兩個問題:
我所有的組件都是在本地注冊的(我使用帶有 Webpack 的 ES6 模塊並在每次需要時在本地導入組件)。 <router-link>
不知道<base-link>
組件是什么並且無法渲染它。 有沒有辦法注入一個本地組件供<router-link>
使用?
為了解決問題 #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
,它允許我們使組件更加透明,即允許我們使用href
或to
等屬性,而無需將它們作為 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.