《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>

相关推荐
颜酱23 分钟前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
Sailing23 分钟前
🚀 别再乱写 16px 了!CSS 单位体系已经进入“计算时代”,真正的响应式布局
前端·css·面试
FansUnion37 分钟前
我如何用 Next.js + Supabase + Cloudflare R2 搭建壁纸销售平台——月成本接近 $0
javascript
喝水的长颈鹿39 分钟前
【大白话前端 03】Web 标准与最佳实践
前端
爱泡脚的鸡腿40 分钟前
Node.js 拓展
前端·后端
左夕2 小时前
分不清apply,bind,call?看这篇文章就够了
前端·javascript
Zha0Zhun3 小时前
一个使用ViewBinding封装的Dialog
前端
兆子龙3 小时前
从微信小程序 data-id 到 React 列表性能优化:少用闭包,多用 data-*
前端
滕青山3 小时前
文本行过滤/筛选 在线工具核心JS实现
前端·javascript·vue.js
时光不负努力3 小时前
编程常用模式集合
前端·javascript·typescript