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

相关推荐
我只会写Bug啊7 分钟前
Vue文件预览终极方案:PNG/EXCEL/PDF/DOCX/OFD等10+格式一键渲染,开源即用!
前端·vue.js·pdf·excel·预览
扯蛋4381 小时前
LangChain的学习之路( 一 )
前端·langchain·mcp
Mr.Jessy2 小时前
Web APIs学习第一天:获取 DOM 对象
开发语言·前端·javascript·学习·html
午安~婉2 小时前
javaScript八股问题
开发语言·javascript·原型模式
西西学代码2 小时前
Flutter---个人信息(5)---持久化存储
java·javascript·flutter
芝麻开门-新起点2 小时前
flutter 生命周期管理:从 Widget 到 State 的完整解析
开发语言·javascript·ecmascript
ConardLi3 小时前
Easy Dataset 已经突破 11.5K Star,这次又带来多项功能更新!
前端·javascript·后端
冴羽3 小时前
10 个被严重低估的 JS 特性,直接少写 500 行代码
前端·javascript·性能优化
rising start3 小时前
四、CSS选择器(续)和三大特性
前端·css
一 乐3 小时前
高校后勤报修系统|物业管理|基于SprinBoot+vue的高校后勤报修系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·毕设