<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组件,它将在其中渲染一个链接。我去掉了与问题无关的任何内容(如rel
、target
、class
等(
理解-我对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;
}
}
}
}
基本上,您可以根据插槽道具在组件内锚点标记上添加任何属性,比如以某些方式导航、添加特殊类,具体取决于您的用例。