Vue - Global and Per-Route Guards
use Global and Per-Route Guards to provide a progress bar when our application has slow internet API calls.
애플리케이션에 느린 인터넷 API 호출이 있을 때 진행률 표시줄을 제공하려면 전역 및 경로별 가드를 사용하세요.
Problem: Our API calls might not always be super fast
Solution #3: Global and Per-Route Guards
/src/router.js
use two new Global Route Guards inside our router.js and make the progress bar appear on every page of our app.
router.js 내에서 두 개의 새로운 Global Route Guard를 사용하고 앱의 모든 페이지에 진행률 표시줄이 나타나도록 하세요.
...
import EventShow from './views/EventShow.vue'
import NProgress from 'nprogress' // <--- include the library
Vue.use(Router)
const router = new Router({ ... })
router.beforeEach((routeTo, routeFrom, next) => {
// Start the route progress bar.
NProgress.start()
next()
})
router.afterEach(() => {
// Complete the animation of the route progress bar.
NProgress.done()
})
export default router
Vue Router Guards Calling Order
- router.beforeEach((routeTo, routeFrom, next))
- beforeRouteUpdate(routeTo, routeFrom, next)
- router.afterEach((routeTo, routeFrom))
- beforeCreate()
- created()
Need a way to not load the component onto the page until it’s done loading, and only then finish the progress bar.
로드가 완료될 때까지 component 를 페이지에 로드하지 않고 이후에 진행률 표시줄만 완료하는 방법이 필요합니다.
This time, use a Route Guard inside our router, rather than inside our component.
이번에는 component 내부가 아닌 라우터 내부에서 Route Guard를 사용하십시오.
/src/router.js
...
import EventShow from './views/EventShow.vue'
import NProgress from 'nprogress'
import store from '@/store/store' // <--- Include our store
Vue.use(Router)
const router = new Router({
mode: 'history',
routes: [
...
{
path: '/event/:id',
name: 'event-show',
component: EventShow,
props: true,
beforeEnter(routeTo, routeFrom, next) { // before this route is loaded
store.dispatch('event/fetchEvent', routeTo.params.id).then(() => {
next()
})
}
}
] ...
By using Vuex Store and the Per-Route inside our router.js, we can dispatch our fetchEvent Action (that we normally would call from our EventShow).and only once that’s returned we allow the navigation to continue by calling next().
Vuex Store와 router.js 내부의 Per-Route를 사용하여 fetchEvent Action(보통 EventShow에서 호출함)을 전달할 수 있습니다. 그리고 반환된 후에만 next()를 호출하여 탐색을 계속할 수 있습니다.
/src/store/modules/event.js
make sure this action returns a promise.
이 작업이 promise를 반환하는지 확인하세요.
...
fetchEvent({ commit, getters, dispatch }, id) {
var event = getters.getEventById(id)
if (event) {
commit('SET_EVENT', event)
} else {
return EventService.getEvent(id) // <--- Add return here
.then(response => {
commit('SET_EVENT', response.data)
})
...
/src/views/EventShow.vue
shrinks a bit.
...
<script>
import { mapState } from 'vuex'
export default {
props: ['id'],
computed: mapState({
event: state => state.event.event
})
}
</script>
Architectural Choice: Removing Vuex from our Components
completely remove Vuex from EventShow, and send in event as a prop from our new Per-Route Guard
EventShow에서 Vuex를 완전히 제거하고 새로운 Per-Route Guard에서 이벤트를 소품으로 보냅니다.
/src/views/EventShow.vue
EventShow component ends up shrinking a lot:
EventShow 구성 요소가 많이 축소됩니다.
...
<script>
export default {
props: {
event: { // Simply receive the event to render
type: Object,
required: true
}
}
}
</script>
...
/src/router.js
The event which is returned are set to the value of routeTo.params.event.
반환되는 이벤트는 RouteTo.params.event 값으로 설정됩니다.
Since props: true is set for the component, params.event gets sent in as the event prop,
컴포넌트에 props: true가 설정되어 있으므로 params.event가 이벤트 prop으로 전송됩니다.
const router = new Router({
mode: 'history',
routes: [
...
{
path: '/event/:id',
name: 'event-show',
component: EventShow,
props: true, // Set params to props
beforeEnter(routeTo, routeFrom, next) {
store.dispatch('event/fetchEvent', routeTo.params.id).then(event => {
routeTo.params.event = event // <--- Set the event we retrieved
next()
})
}
}
/src/store/modules/event.js
then callback now has an event parameter, which is filled by the event that returns from the API.
이제 콜백에는 API에서 반환되는 이벤트로 채워지는 이벤트 parameter가 있습니다.
To make sure the value gets sent in the callback, we’ll need to add two returns to our event Module:
콜백에서 값이 전송되도록 하려면 이벤트 모듈에 두 개의 반환을 추가해야 합니다.
...
fetchEvent({ commit, getters, dispatch }, id) {
var event = getters.getEventById(id)
if (event) {
commit('SET_EVENT', event)
return event // <--- Added return here
} else {
return EventService.getEvent(id)
.then(response => {
commit('SET_EVENT', response.data)
return response.data // <--- Added a return here
})
Resources
https://github.com/Code-Pop/real-world-vue/releases/tag/progress-bar-global-guard
Release progress-bar-global-guard · Code-Pop/real-world-vue
Removing Vuex from EventShow
github.com
https://router.vuejs.org/guide/advanced/navigation-guards.html
Navigation Guards | Vue Router
Navigation Guards As the name suggests, the navigation guards provided by Vue router are primarily used to guard navigations either by redirecting it or canceling it. There are a number of ways to hook into the route navigation process: globally, per-route
router.vuejs.org
https://router.vuejs.org/guide/advanced/navigation-guards.html#per-route-guard
Navigation Guards | Vue Router
Navigation Guards As the name suggests, the navigation guards provided by Vue router are primarily used to guard navigations either by redirecting it or canceling it. There are a number of ways to hook into the route navigation process: globally, per-route
router.vuejs.org