Create a new project using vue-cli without vue-router or VueX
Create /views directory and inside Home and Blog component
Create BaseLayout component that will have header, footer and content slot and register it globally.
Create DummyNavigator component
navigator will get routes object prop
when routeChange event triggered navigator will switch displayed component based on provided prop
navigator will use history api to change browser url
from vue cli:
vue add vue-router
from vue ui
router injected into Vue instance
route url
route name - use this for navigation
per route code splitting technique
history mode will won't show hash in url
That will need server setup to serve always index.html
where to navigate on click
where to present component
use name instead of url
if url will change in the future it will require only one place to change it
pass params to about route
dynamic routes
routes that get params based on their url
what we will get
by setting props: true we will enable to pass props on param object and spread params into component
let's pass post id in url
You can also pass props using object notation for static props
Or a function
props: { showSidebar: false } }
props: (route) => ({ query: route.query.q }) }
Note: in a real-world scenario we won't pass post in props, but will use VueX to get post by id
posts array on data object
pass post as a prop
BlogComponent.js
Caveat: PostComponent won't be rerendered if the route will change from post/1 to post/2
So logic in created() lifecycle hook need to moved elsewhere
Use NavigationGuards
watch $route changes
If this happens in nested route, we just need to add a :key to router-view
You can catch all other routes using *
when using * pathMatch is added to $route params
Vue router expose $route and $router object that can be used to navigate programmatically
router.replace(location, onComplete?, onAbort?)
matches on any route matches 'home' named route path even when just starting with it
matches on exact route matches 'about' named route path
match exact path
v-slot directive to get access to router-link data
If you don't pass single child, router-link will wrap in span element
to get query string from url you can simply access $route.query
Sometimes you want multiple views to be updated for a route change
will be rendered inside <router-view> in BlogComponent
An alias of /a as /b means when the user visits /b, the URL remains /b, but it will be matched as if the user is visiting /a.
This will mean for example that if you go to /post it will load BlogComponent and $route.name will be blog
you can use a function, an object with a named route or a string with route to redirect to
You can define either global, per route or in-component navigation guards to do some logic in different state of resolving the route
route to navigate to
route to navigate from
next function that must be called once to resolve navigation
next function accept a boolean next(false) won't navigate
will accept anything router-link or router.push accepts
instance of Error - navigation will be aborted and onError will trigger
beforeEnter - use this guard before navigation is confirmed.
beforeResolve - will be called after all in-component guards will be resolved and async components loaded
afterEach - will be called after navigation is resolved, but cannot affect the route
beforeRouteLeave - used usually for confirmation if user wants to leave the page
beforeRouteEnter - called before route is confirmed. There is no access to component up until route is confirmed: next(cmp => {})
beforeRouteUpdate - component is available so you can access this
Meta fields are used to pass additional data to components. often for auth
to access meta field we need to access matched route record
route can match multiple routes so we need to check matched array to see if any of the matched routes is protected
we will typically put a redirect query string to know where to redirect once logged in