《Vue Router实战教程》21.扩展 RouterLink

欢迎观看《Vue Router 实战(第4版)》视频课程

    1. 扩展 RouterLink

RouterLink 组件提供了足够的 props 来满足大多数基本应用程序的需求,但它并未尝试涵盖所有可能的用例,在某些高级情况下,你可能会发现自己使用了 v-slot。在大多数中型到大型应用程序中,值得创建一个(如果不是多个)自定义 RouterLink 组件,以在整个应用程序中重用它们。例如导航菜单中的链接,处理外部链接,添加 inactive-class 等。

让我们扩展 RouterLink 来处理外部链接,并在 AppLink.vue 文件中添加一个自定义的 inactive-class:

Composition API

<script setup>

import { computed } from 'vue'

import { RouterLink } from 'vue-router'

defineOptions({

inheritAttrs: false,

})

const props = defineProps({

// 如果使用 TypeScript,请添加 @ts-ignore

...RouterLink.props,

inactiveClass: String,

})

const isExternalLink = computed(() => {

return typeof props.to === 'string' && props.to.startsWith('http')

})

</script>

<template>

<a v-if="isExternalLink" v-bind="$attrs" :href="to" target="_blank">

<slot />

</a>

<router-link

v-else

v-bind="$props"

custom

v-slot="{ isActive, href, navigate }"

>

<a

v-bind="$attrs"

:href="href"

@click="navigate"

:class="isActive ? activeClass : inactiveClass"

>

<slot />

</a>

</router-link>

</template>

如果你喜欢使用渲染函数或创建 computed 属性,你可以使用 Composition API 中的 useLink :

import { RouterLink, useLink } from 'vue-router'

export default {

name: 'AppLink',

props: {

// 如果使用 TypeScript,请添加 @ts-ignore

...RouterLink.props,

inactiveClass: String,

},

setup(props) {

// `props` 包含 `to` 和任何其他可以传递给 <router-link> 的 prop

const { navigate, href, route, isActive, isExactActive } = useLink(props)

// profit!

return { isExternalLink }

},

}

在实践中,你可能希望将你的 AppLink 组件用于应用程序的不同部分。例如,使用 Tailwind CSS,你可以用所有的类创建一个 NavLink.vue 组件:

<template>

<AppLink

v-bind="$attrs"

class="inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out"

active-class="border-indigo-500 text-gray-900 focus:border-indigo-700"

inactive-class="text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:text-gray-700 focus:border-gray-300"

>

<slot />

</AppLink>

</template>

Options API

<script>

import { RouterLink } from 'vue-router'

export default {

name: 'AppLink',

inheritAttrs: false,

props: {

// 如果使用 TypeScript,请添加 @ts-ignore

...RouterLink.props,

inactiveClass: String,

},

computed: {

isExternalLink() {

return typeof this.to === 'string' && this.to.startsWith('http')

},

},

}

</script>

<template>

<a v-if="isExternalLink" v-bind="$attrs" :href="to" target="_blank">

<slot />

</a>

<router-link

v-else

v-bind="$props"

custom

v-slot="{ isActive, href, navigate }"

>

<a

v-bind="$attrs"

:href="href"

@click="navigate"

:class="isActive ? activeClass : inactiveClass"

>

<slot />

</a>

</router-link>

</template>

如果你喜欢使用渲染函数或创建 computed 属性,你可以使用 Composition API 中的 useLink :

import { RouterLink, useLink } from 'vue-router'

export default {

name: 'AppLink',

props: {

// 如果使用 TypeScript,请添加 @ts-ignore

...RouterLink.props,

inactiveClass: String,

},

setup(props) {

// `props` 包含 `to` 和任何其他可以传递给 <router-link> 的 prop

const { navigate, href, route, isActive, isExactActive } = useLink(props)

// profit!

return { isExternalLink }

},

}

在实践中,你可能希望将你的 AppLink 组件用于应用程序的不同部分。例如,使用 Tailwind CSS,你可以用所有的类创建一个 NavLink.vue 组件:

<template>

<AppLink

v-bind="$attrs"

class="inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out"

active-class="border-indigo-500 text-gray-900 focus:border-indigo-700"

inactive-class="text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:text-gray-700 focus:border-gray-300"

>

<slot />

</AppLink>

</template>

相关推荐
杨大厨wd19 小时前
Vue3 业务组件封装别只会传 props:如何设计一个真正好用的组件
vue.js
前端那点事19 小时前
Vue3 script setup 语法糖最全教程!零基础吃透+项目落地+面试满分
前端·vue.js
ConardLi19 小时前
Harness 实践:让 Agent 全自动制作知识讲解视频
前端·人工智能·后端
费曼学习法19 小时前
React Hooks 源码级揭秘:为什么必须按顺序调用?
javascript·react.js
努力干饭中19 小时前
Vibe Coding 第二弹:做一个 Canvas K线图
前端·canvas·vibecoding
卷帘依旧20 小时前
Vue 响应式原理:Object.defineProperty vs Proxy 深度对比
前端·vue.js
yqcoder20 小时前
原生 AJAX 揭秘:如何使用 XHR 发起请求
前端·ajax·okhttp
ZC跨境爬虫20 小时前
跟着 MDN 学 HTML day_34:(深入XML 中的 CDATASection 接口)
xml·前端·html·html5·媒体
之歆20 小时前
DAY_20JavaScript 条件语句与循环结构深度学习(二)
前端·javascript
山北雨夜漫步20 小时前
LangGraph
java·前端·算法