RouterLink ํ์ฅํ๊ธฐ โ
RouterLink ์ปดํฌ๋ํธ๋ ๋๋ถ๋ถ์ ๊ธฐ๋ณธ ์ ํ๋ฆฌ์ผ์ด์
์ ์ถฉ๋ถํ props
๋ฅผ ์ ๊ณตํ์ง๋ง, ๋ชจ๋ ๊ฐ๋ฅํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ค๋ฃจ๋ ค๊ณ ํ์ง๋ ์์ผ๋ฏ๋ก ๊ณ ๊ธ ์ผ์ด์ค์์๋ v-slot
์ ์ฌ์ฉํ๊ฒ ๋ ๊ฒ์
๋๋ค. ๋๋ถ๋ถ์ ์ค๋ํ ์ ํ๋ฆฌ์ผ์ด์
์์๋ ํ๋ ์ด์์ ์ปค์คํ
RouterLink ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ์ ํ๋ฆฌ์ผ์ด์
์ ๋ฐ์์ ์ฌ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์๋ฅผ ๋ค์ด ๋ด๋น๊ฒ์ด์
๋ฉ๋ด์ ๋งํฌ, ์ธ๋ถ ๋งํฌ ์ฒ๋ฆฌ, inactive-class
์ถ๊ฐ ๋ฑ์ด ์์ต๋๋ค.
์ด์ RouterLink๋ฅผ ํ์ฅํ์ฌ ์ธ๋ถ ๋งํฌ๋ ์ฒ๋ฆฌํ๊ณ , AppLink.vue
ํ์ผ์์ ์ปค์คํ
inactive-class
๋ฅผ ์ถ๊ฐํด๋ณด๊ฒ ์ต๋๋ค:
<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>
<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)
// ์ด๋!
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>