如何根据<router-link> <a> 链接是外部的还是内部的来动态渲染或在 Vue 中?


<template>
<component
:is="type === 'internal' ? 'router-link' : 'a'"
:to="type === 'internal' ? link : null"
:href="type !== 'internal' ? link : null"
>
<slot />
</component>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
@Component
export default class SiteLink extends Vue {
@Prop({
validator: (value: string) =>
["external", "internal"].includes(value)
})
private readonly type!: string;
@Prop({ type: String })
private readonly link!: string;
}
</script>

上面是一个Vue组件,它将在其中渲染一个链接。我去掉了与问题无关的任何内容(如reltargetclass等(

理解-我对Vue Router的理解是,<router-link to="/about">About</router-link><a href="/about">About</a>都将在DOM中呈现为<a href="/about">About</a>,不同之处在于<router-link>版本将为链接提供SPA功能(即不加载新页面,而是动态呈现组件(。

预期-当type="internal"时,它将呈现<router-link>版本。当type="external"时,它将呈现<a>版本。

<site-link type="external" link="https://stackoverflow.com">Stack Overflow</site-link>
Will render
<a href="https://stackoverflow.com">Stack Overflow</a>
<site-link type="internal" link="/about">About</site-link>
Will render
<router-link to="/about">About</router-link>
Which is then handle by VueRouter to render
<a href="/about">About</a>

实际-当type="internal"时,在DOM中呈现没有href<a>。当type="external"时,它将按预期进行渲染。

<site-link type="external" link="https://stackoverflow.com">Stack Overflow</site-link>
Will render
<a href="https://stackoverflow.com">Stack Overflow</a>
<site-link type="internal" link="/about">About</site-link>
Will render
<router-link to="/about">About</router-link>
Which is then handle by VueRouter to render
<a>About</a> <!-- Notice there is no href -->

有什么想法可以实现我想要的吗?

更好、更干净的方法:

<router-link v-if="type === 'internal' :to="link">
<slot />
</router-link>
<a v-else :ref="link"> <slot /> </a>

你可以在根元素中使用v-if,这样它就解决了的问题

或者你可能只是错过了路径的一部分?

<component
:is="type === 'internal' ? 'router-link' : 'a'"
:to="type === 'internal' ? { path: link } : null"
:href="type !== 'internal' ? link : null"
>
<slot />
</component>

官方文档中包含了一个如何立即执行此操作的示例。

  • 扩展RouterLink

他们的方法是创建一个处理外部链接的自定义模板。

。。。不同之处在于<router-link>版本将为链接提供SPA功能(即不加载新页面,而是动态呈现组件(。

不加载新页面,我想你的意思是它不会重新加载页面。是的,它没有,因为onclick处理程序实际上被分配给了一个函数,该函数在将新条目推入历史堆栈时执行preventDefault(防止页面重定向(。

如果您查看API参考,<router-link>为您做的最值得注意的事情是,它根据活动/当前路由在active-class之间切换。

因此,也就是说,您可以通过v-slot在默认插槽内进行动态<a>nchor渲染;因为在这一点上,href槽道具将是一个解析的URL,然后您可以安全地将其绑定到DOMhref属性。


编辑

添加了一个示例(未经测试(。

<router-link
:to="link"
v-slot="{ href, route, navigate, isActive, isExactActive }">
<a
:class="isActive ? 'your-custom-class' : 'anything'"
:href="type !== 'internal' ? href : 'javascript:void(0);'"
@click="customNavigate(navigate.bind($event))">
<slot></slot>
</a>
</router-link>

其中customNavigate处理程序可能类似于:

{
methods: {
customNavigate(navigate) {
if (this.type === 'internal') {
navigate();
return false;
}
}
}
}

基本上,您可以根据插槽道具在组件内锚点标记上添加任何属性,比如以某些方式导航、添加特殊类,具体取决于您的用例。

最新更新