Vue Router์ Composition API โ
Vue์ Composition API์ ๋์
์ผ๋ก ์๋ก์ด ๊ฐ๋ฅ์ฑ์ด ์ด๋ ธ์ง๋ง, Vue Router์ ๋ชจ๋ ์ ์ฌ๋ ฅ์ ํ์ฉํ๋ ค๋ฉด this
์ ๋ํ ์ ๊ทผ๊ณผ ์ปดํฌ๋ํธ ๋ด ๋ค๋น๊ฒ์ด์
๊ฐ๋๋ฅผ ๋์ฒดํ ๋ช ๊ฐ์ง ์๋ก์ด ํจ์๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
setup
๋ด๋ถ์์ Router์ ํ์ฌ Route์ ์ ๊ทผํ๊ธฐ โ
setup
๋ด๋ถ์์๋ this
์ ์ ๊ทผํ ์ ์๊ธฐ ๋๋ฌธ์, this.$router
๋ this.$route
์ ์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค. ๋์ , useRouter
์ useRoute
์ปดํฌ์ ๋ธ์ ์ฌ์ฉํฉ๋๋ค:
<script setup>
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
function pushWithQuery(query) {
router.push({
name: 'search',
query: {
...route.query,
...query,
},
})
}
</script>
route
๊ฐ์ฒด๋ ๋ฐ์ํ ๊ฐ์ฒด์
๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ, ์ ์ฒด route
๊ฐ์ฒด๋ฅผ ๊ฐ์ํ๋ ๊ฒ์ ํผํด์ผ ํฉ๋๋ค. ๋์ , ๋ณ๊ฒฝ๋ ๊ฒ์ผ๋ก ์์๋๋ ์์ฑ๋ง ์ง์ ๊ฐ์ํ ์ ์์ต๋๋ค:
<script setup>
import { useRoute } from 'vue-router'
import { ref, watch } from 'vue'
const route = useRoute()
const userData = ref()
// params๊ฐ ๋ณ๊ฒฝ๋ ๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ต๋๋ค
watch(
() => route.params.id,
async newId => {
userData.value = await fetchUser(newId)
}
)
</script>
ํ
ํ๋ฆฟ์์๋ ์ฌ์ ํ $router
์ $route
์ ์ ๊ทผํ ์ ์์ผ๋ฏ๋ก, ํด๋น ๊ฐ์ฒด๋ค์ด ํ
ํ๋ฆฟ์์๋ง ํ์ํ๋ค๋ฉด useRouter
๋ useRoute
๋ฅผ ์ฌ์ฉํ ํ์๊ฐ ์์ต๋๋ค.
๋ค๋น๊ฒ์ด์ ๊ฐ๋ โ
Vue Router๋ Composition API ํจ์๋ก ์ ๋ฐ์ดํธ ๋ฐ ์ดํ ๊ฐ๋๋ฅผ ์ ๊ณตํฉ๋๋ค:
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { ref } from 'vue'
// beforeRouteLeave ์ต์
๊ณผ ๋์ผํ์ง๋ง `this`์ ์ ๊ทผํ ์ ์์ต๋๋ค
onBeforeRouteLeave((to, from) => {
const answer = window.confirm(
'์ ๋ง๋ก ์ด ํ์ด์ง๋ฅผ ๋ ๋์๊ฒ ์ต๋๊น? ์ ์ฅ๋์ง ์์ ๋ณ๊ฒฝ์ฌํญ์ด ์์ต๋๋ค!'
)
// ๋ค๋น๊ฒ์ด์
์ ์ทจ์ํ๊ณ ๊ฐ์ ํ์ด์ง์ ๋จธ๋ฌด๋ฆ
๋๋ค
if (!answer) return false
})
const userData = ref()
// beforeRouteUpdate ์ต์
๊ณผ ๋์ผํ์ง๋ง `this`์ ์ ๊ทผํ ์ ์์ต๋๋ค
onBeforeRouteUpdate(async (to, from) => {
// id๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉ์๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ์ฟผ๋ฆฌ๋ ํด์๋ง ๋ณ๊ฒฝ๋์์ ์๋ ์๊ธฐ ๋๋ฌธ์
๋๋ค
if (to.params.id !== from.params.id) {
userData.value = await fetchUser(to.params.id)
}
})
</script>
Composition API ๊ฐ๋๋ <router-view>
์ ์ํด ๋ ๋๋ง๋๋ ๋ชจ๋ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ์ปดํฌ๋ํธ ๋ด ๊ฐ๋์ฒ๋ผ ๋ฐ๋์ ๋ผ์ฐํธ ์ปดํฌ๋ํธ์์ ์ง์ ์ฌ์ฉํ ํ์๋ ์์ต๋๋ค.
useLink
โ
Vue Router๋ RouterLink์ ๋ด๋ถ ๋์์ ์ปดํฌ์ ๋ธ๋ก ์ ๊ณตํฉ๋๋ค. ์ด๋ RouterLink
์ props์ ๊ฐ์ ๋ฐ์ํ ๊ฐ์ฒด๋ฅผ ๋ฐ์, ๋๋ง์ RouterLink
์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ฑฐ๋ ์ปค์คํ
๋งํฌ๋ฅผ ์์ฑํ ์ ์๋ ์ ์์ค ์์ฑ๋ค์ ๋
ธ์ถํฉ๋๋ค:
<script setup>
import { RouterLink, useLink } from 'vue-router'
import { computed } from 'vue'
const props = defineProps({
// TypeScript๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ @ts-ignore๋ฅผ ์ถ๊ฐํ์ธ์
...RouterLink.props,
inactiveClass: String,
})
const {
// ํด์๋ ๋ผ์ฐํธ ๊ฐ์ฒด
route,
// ๋งํฌ์์ ์ฌ์ฉํ href
href,
// ๋งํฌ๊ฐ ํ์ฑ ์ํ์ธ์ง ๋ํ๋ด๋ boolean ref
isActive,
// ๋งํฌ๊ฐ ์ ํํ ํ์ฑ ์ํ์ธ์ง ๋ํ๋ด๋ boolean ref
isExactActive,
// ๋งํฌ๋ก ๋ค๋น๊ฒ์ด์
ํ๋ ํจ์
navigate
} = useLink(props)
const isExternalLink = computed(
() => typeof props.to === 'string' && props.to.startsWith('http')
)
</script>
RouterLink์ v-slot
์ useLink
์ปดํฌ์ ๋ธ๊ณผ ๋์ผํ ์์ฑ์ ์ ๊ทผํ ์ ์๋ค๋ ์ ์ ์ ์ํ์ธ์.