Navigation Guard
๋ค๋น๊ฒ์ด์ ๊ฐ๋
โ Vue router๋ฅผ ํตํด ํน์ URL์ ์ ๊ทผํ ๋ ๋ค๋ฅธ url๋ก redirect ํ๊ฑฐ๋ ํด๋น URL๋ก์ ์ ๊ทผ์ ๋ง๋ ๋ฐฉ๋ฒ
๋ค๋น๊ฒ์ด์ ๊ฐ๋์ ์ข ๋ฅ
โ ์ ์ญ ๊ฐ๋: ์ ํ๋ฆฌ์ผ์ด์
์ ์ญ์์ ๋์
โ ๋ผ์ฐํฐ ๊ฐ๋: ํน์ url์์๋ง ๋์
โ ์ปดํฌ๋ํธ ๊ฐ๋: ๋ผ์ฐํฐ ์ปดํฌ๋ํธ ์์ ์ ์
์ ์ญ ๊ฐ๋
Global Before Guard
โ ๋ค๋ฅธ url ์ฃผ์๋ก ์ด๋ํ ๋ ํญ์ ์คํ
โ router/index.js
์ router.beforeEach()
๋ฅผ ์ฌ์ฉํ์ฌ ์ค์
โ ์ฝ๋ฐฑ ํจ์์ ๊ฐ์ผ๋ก ๋ค์ 3๊ฐ์ ์ธ์๋ฅผ ๋ฐ๋๋ค
- to: ์ด๋ํ url ์ ๋ณด๊ฐ ๋ด๊ธด Route ๊ฐ์ฒด
- from: ํ์ฌ url ์ ๋ณด๊ฐ ๋ด๊ธด route ๊ฐ์ฒด
- next: ์ง์ ํ url๋ก ์ด๋ํ๊ธฐ ์ํด ํธ์ถํ๋ ํจ์
- ์ฝ๋ฐฑ ํจ์ ๋ด๋ถ์์ ๋ฐ๋์ ํ ๋ฒ๋ง ํธ์ถ
- ๊ธฐ๋ณธ์ ์ผ๋ก to์ ํด๋นํ๋ url๋ก ์ด๋
โ URL์ด ๋ณ๊ฒฝ๋์ด ํ๋ฉด์ด ์ ํ๋๊ธฐ ์ router.beforeEach()
ํธ์ถ
- ํ๋ฉด์ด ์ ํ๋์ง ์๊ณ ๋๊ธฐ ์ํ๊ฐ ๋๋ค
โ ๋ณ๊ฒฝ๋ URL๋ก ๋ผ์ฐํ ๋๊ธฐ ์ํด์๋ next() ํธ์ถ ํ์
- next() ํธ์ถ๋๊ธฐ ์ ๊น์ง ํ๋ฉด์ด ์ ํ๋์ง ์๋๋ค.
Global Before Guard
// router/index.js
...
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to, from, next) => {
console.log('to', to)
console.log('from', from)
console.log('next', next)
})
โ /home/
์ผ๋ก ์ด๋ํ๋๋ผ๋ ๋ผ์ฐํ
์ด ๋์ง ์๊ณ ์์ ๊ฐ์ด ๋ก๊ทธ๋ง ์ถ๋ ฅ๋๋ค.
โ next()
๊ฐ ํธ์ถ๋์ง ์์ผ๋ฉด ํ๋ฉด์ด ์ ํ๋์ง ์๋๋ค.
// router/index.js
...
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to, from, next) => {
console.log('to', to)
console.log('from', from)
console.log('next', next)
next()
})
export default router
โ to์๋ ์ด๋ํ url์ธ about์ ๋ํ ์ ๋ณด
โ from์๋ ํ์ฌ url์ธ home์ ๋ํ ์ ๋ณด
Login ์ฌ๋ถ์ ๋ฐ๋ฅธ ๋ผ์ฐํ ์ฒ๋ฆฌ
- Login์ด ๋์ด ์์ง ์๋ค๋ฉด Login ํ์ด์ง๋ก ์ด๋ํ๋ ๊ธฐ๋ฅ ์ถ๊ฐ
// views/LoginView.vue
<template>
<div>
<h1>๋ก๊ทธ์ธ ํ์ด์ง</h1>
</div>
</template>
<script>
export default {
name: 'LoginView'
}
</script>
<style>
</style>
// router/index.js
import LoginView from '@/views/LoginView'
Vue.use(VueRouter)
const routes = [
{
path: '/login',
name: 'login',
component: LoginView
}
]
- LoginView์ ๋ํ ๋ผ์ฐํฐ ๋งํฌ ์ถ๊ฐ
// App.vue
<template>
<div id="app">
<nav>
...
<router-link :to="{ name: 'login' }">Login</router-link>
</nav>
- Login ์ฌ๋ถ์ ๋ฐ๋ฅธ ๋ผ์ฐํ ์ฒ๋ฆฌ
// router/index.js
router.beforeEach((to, from, next) => {
// ๋ก๊ทธ์ธ ์ฌ๋ถ(์์๋ก)
const isLoggedIn = true
// ๋ก๊ทธ์ธ์ด ํ์ํ ํ์ด์ง
const authPages = ['hello']
// ์ํ๋ก ์ด๋ํ ํ์ด์ง(to)๊ฐ ๋ก๊ทธ์ธ์ด ํ์ํ ์ฌ์ดํธ์ธ์ง ํ์ธ
const isAuthRequired = authPages.includes(to.name)
if (isAuthRequired && !isLoggedIn) {
next({ name: 'login' })
} else {
next()
}
})
โ isAuthRequired ๊ฐ์ ๋ฐ๋ผ ๋ก๊ทธ์ธ์ด ํ์ํ ํ์ด์ง์ด๊ณ ๋ก๊ทธ์ธ์ด ์๋์ด ์์ผ๋ฉด Login ํ์ด์ง๋ก ์ด๋
- view๊ฐ ์ฌ๋ฌ ๊ฐ๋ผ๋ฉด
// router/index.js
router.beforeEach((to, from, next) => {
// ๋ก๊ทธ์ธ ์ฌ๋ถ(์์๋ก)
const isLoggedIn = true
const allowAllPages = ['login']
// ์ํ๋ก ์ด๋ํ ํ์ด์ง(to)๊ฐ ๋ก๊ทธ์ธ์ด ํ์ํ ์ฌ์ดํธ์ธ์ง ํ์ธ
const isAuthRequired = !allowAllPages.includes(to.name)
if (isAuthRequired && !isLoggedIn) {
next({ name: 'login' })
} else {
next()
}
})
โ Login ํ์ง ์์๋ ๋๋ ํ์ด์ง๋ฅผ ๋ชจ์๋ ์ ์๋ค.
๋ผ์ฐํฐ ๊ฐ๋
๊ฐ์
โ ์ ์ฒด route๊ฐ ์๋ ํน์ route์ ๋ํด์๋ง ๊ฐ๋ ์ค์
โ beforEnter()
- route์ ์ง์ ํ์ ๋ ์คํ
- ๋ผ์ฐํฐ๋ฅผ ๋ฑ๋กํ ์์น์ ์ถ๊ฐ
- ๋จ ๋งค๊ฐ๋ณ์, ์ฟผ๋ฆฌ, ํด์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ ์คํ๋์ง ์๊ณ ๋ค๋ฅธ ๊ฒฝ๋ก์์ ํ์ํ ๋๋ง ์คํ
- ์ฝ๋ฐฑ ํจ์๋ to, from, next๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค.
Login ์ฌ๋ถ์ ๋ฐ๋ฅธ ๋ผ์ฐํ ์ฒ๋ฆฌ
โ ์ด๋ฏธ ๋ก๊ทธ์ธ ๋์ด ์๋ ๊ฒฝ์ฐ์ HomeView๋ก ์ด๋ํ๊ธฐ
// router/index.js
const isLoggedIn = true
const routes = [
{
path: '/login',
name: 'login',
component: LoginView,
beforeEnter: (to, from, next) => {
if (isLoggedIn === true) {
console.log('์ด๋ฏธ ๋ก๊ทธ์ธ')
next({ name: 'home' })
} else {
next()
}
}
}
]
โ ๋ก๊ทธ์ธ ์ฌ๋ถ์ ๋ํ ์์ ๋ณ์ ์์ฑ
โ ๋ก๊ทธ์ธ์ด ๋์ด ์๋ ๊ฒฝ์ฐ home์ผ๋ก ์ด๋
โ ๋ก๊ทธ์ธ์ด ๋์ด ์์ง ์์ ๊ฒฝ์ฐ login์ผ๋ก ์ด๋
์ปดํฌ๋ํธ ๊ฐ๋
๊ฐ์
โ ํน์ ์ปดํฌ๋ํธ ๋ด์์ ๊ฐ๋๋ฅผ ์ง์ ํ๊ณ ์ถ์ ๋ ์ฌ์ฉ
โ beforeRouteUpdate()
: ํด๋น ์ปดํฌ๋ํธ๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฒฝ๋ก๊ฐ ๋ณ๊ฒฝ๋ ๋
Params ๋ณํ ๊ฐ์ง
โ navbar์ ์๋ Hello๋ฅผ ๋๋ฅด๋ฉด sunjun์๊ฒ ์ธ์ฌํ๋ ํ์ด์ง๋ก ์ด๋ํ๋ฉด URL์ ๋ณํ์ง๋ง ํ์ด์ง๋ ๋ณํํ์ง ์๋๋ค.
โ ๋ณํํ์ง ์๋ ์ด์
- ์ปดํฌ๋ํธ๊ฐ ์ฌ์ฌ์ฉ ๋์๊ธฐ ๋๋ฌธ์ lifecycle hook์ด ํธ์ถ๋์ง ์๊ณ , ๋ฐ๋ผ์
$route.params
์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์๋ก ๊ฐ์ ธ์ค์ง ์๋๋ค.
<script>
export default {
name: 'HelloView',
data() {
return {
userName: this.$route.params.userName
}
},
beforeRouteUpdate(to, from, next) {
this.userName = to.params.userName
next()
}
}
</script>
โ userName์ ์ด๋ํ params์ ์๋ userName์ผ๋ก ์ฌํ ๋น
404 Not Found
404 Not Found
// views/NotFound404
<template>
<div>
<h1>404 Not Found</h1>
</div>
</template>
<script>
export default {
name: 'NotFound404'
}
</script>
// router/index.js
import NotFound404 from '@/views/NotFound404'
Vue.use(VueRouter)
const routes = [
...
{
path: '/404',
name: 'NotFound404',
component: NotFound404
},
]
์์ฒญํ ๋ฆฌ์์ค๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ
// router/index.js
const routes = [
...
{
path: '*',
redirect: '/404
},
]
โ ๋ชจ๋ ๊ฒฝ๋ก์ ๋ํด 404page๋ก redirect ์ํค๊ธฐ
- ๊ธฐ์กด์ ๋ช ์ํ ๊ฒฝ๋ก๊ฐ ์๋ ๋ชจ๋ ๊ฒฝ๋ก๊ฐ 404page๋ก redirect
- routes ์ตํ๋จ๋ถ์ ์์ฑํด์ผ ํ๋ค
ํ์์ ์ ํจํ์ง๋ง ํน์ ๋ฆฌ์์ค๋ฅผ ์ฐพ์ ์ ์๋ ๊ฒฝ์ฐ
โ ๊ฐ์์ง ์ฌ์ง ์ถ๋ ฅ ํ์ด์ง
<template>
<div>
<img :src="imgSrc" alt="">
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'DogView',
data() {
return {
imgSrc: null,
}
},
methods: {
getDogImage() {
const breed = this.$route.params.breed
const dogImageUrl = `https://dog.ceo/api/breed/${breed}/images/random`
axios({
method: 'get',
url: dogImageUrl
})
.then((response) => {
const imgSrc = response.data.message
this.imgSrc = imgSrc
})
.catch((error) => {
console.log(error)
})
}
},
created() {
this.getDogImage()
}
}
</script>
<style>
</style>
// views/DogView.vue
const routes = [
...
{
path: '/dog/:breed',
name: 'dog',
component: DogView
},
]
โ Dog api axios ๋ก์ง ์์ฑ
// views/DogView.vue
<template>
<div>
<p v-if="!imgSrc">{{ message }}</p>
<img :src="imgSrc" alt="">
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'DogView',
data() {
return {
imgSrc: null,
message: '๋ก๋ฉ์ค...'
}
},
...
}
// views/DogView.vue
axios({
method: 'get',
url: dogImageUrl
})
.then((response) => {
const imgSrc = response.data.message
this.imgSrc = imgSrc
})
.catch((error) => {
this.message=`${this.$route.params.breed}๋ ์๋ ํ์ข
์
๋๋ค.`
console.log(error)
})
โ ์์ฒญ ์คํจ์ error์์ ๋ฉ์์ง ์ถ๋ ฅํ๊ธฐ
404 Not Found๋ก ์ด๋ ์ํค๊ธฐ
// views/DogView.vue
axios({
method: 'get',
url: dogImageUrl
})
.then((response) => {
const imgSrc = response.data.message
this.imgSrc = imgSrc
})
.catch((error) => {
this.$router.push('/404')
console.log(error)
})
'โญ Personal_Study > Vue' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Vue with DRF: Server & Client (0) | 2022.11.20 |
---|---|
Article with Vue (0) | 2022.11.19 |
Vue Router (0) | 2022.11.18 |
UX & UI (0) | 2022.11.18 |
Todo: Local Storage (0) | 2022.11.16 |
๋๊ธ