Vue-router essentially maps urls to components
Route:
Dynamic routing
We all have our own home page, and we use the same component to display the content of the home page, so we just need to change the id of the user passed in to display the corresponding user content, rather than rewriting a component.
For example: juejin. Cn/user / 449027… ; Change the following ID to be a different user
Const router = new VueRouter({routes: [// dynamic route parameters start with a colon {path: '/user/:id', Component: user}, // multi-route {path: '/user/:id', component: user}, // multi-route {path: '/city/:cityname/house/:house_id', } ] })Copy the code
Path parameters are marked with a colon:. When a route is matched, the parameter value is set to this.$route.params, which can be used within each component.
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
Copy the code
const City = {
template: '<div>City {{ $route.params.cityname }} -- House {{house_id}}</div>'
}
Copy the code
Routing change
When routing parameters are used, the original component instance is reused, which is more efficient than destroying and recreating it. However, this also means that the component’s lifecycle hooks are no longer called.
But it triggers the route’s navigational guard: beforeRouteUpdate
There are two methods to detect the change of routing objects:
const User = { template: '... ', watch: {$route(to, from) {$route(to, from) { }}}Copy the code
const User = { template: '... ', beforeRouteUpdate(to, from, next) { // react to route changes... // don't forget to call next() } }Copy the code
Captures an unspecified route
Regular arguments only match characters in URL fragments delimited by /. If we want to match any path that is not specified, we can use the wildcard (*) :
{/ / will match all path path: '*'} {/ / will match with ` / user - ` path at the beginning of arbitrary path: '/ user - *}Copy the code
When using wildcard routes, ensure that the order of routes is correct, that is, routes containing wildcards should be placed last. The route {path: ‘*’} is usually used for client 404 errors.
$route.params automatically adds a parameter named pathMatch. It contains parts of the URL that are matched by wildcards:
// give a route {path: '/user-*'} this.$route.push ('/user- *') this.$route.params.pathMatch // 'admin' // give a route {path: '*' } this.$router.push('/non-existing') this.$route.params.pathMatch // '/non-existing'Copy the code
Embedded routines by
The dynamic path segments in the URL also correspond to nested layer components in a certain structure. With vue-Router, this relationship can be easily expressed using nested routines.
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [{// If /user/:id/profile matches successfully, // UserProfile will be rendered in user's <router-view> path: 'profile', Component: UserProfile}, {// When /user/:id/posts match successfully // UserPosts will be rendered in user <router-view> path: 'posts', component: UserPosts } ] } ] })Copy the code
Components are nested
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
Copy the code
Note that nested paths starting with/are treated as root paths. This lets you make full use of nested components without having to set nested paths. The root of a Vue file is a nested path starting with a slash
<div id="app">
<router-view/>
</div>
Copy the code
After routing
You can set the name of a route in the Routes configuration when creating the Router instance.
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
Copy the code
To link to a named route, pass an object to router-link’s to property:
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
Copy the code
Named view
Instead of having a single exit, you can have multiple individually named views in the interface. If router-view does not have a name, it defaults to default.
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="helper"></router-view>
Copy the code
You can then complete the layout with this routing configuration:
{path: '/ Settings ', // You can also configure named views on top-level routing. Component: UserSettings, children: [{path: 'emails', Component: UserEmailsSubscriptions }, { path: 'profile', components: { default: UserProfile, helper: UserProfilePreview, a: Loading } }] }Copy the code
Route redirection and alias
redirect
Redirection is also done using the Routes configuration, as shown in the following example:
Const router = new VueRouter({routes: [// redirect from '/a' to '/ b '{path: '/a', redirect: '/b'}, // The redirect target can also be a named route {path: '/c', redirect: {name: 'foo'}}, // even a method that dynamically returns the redirect target {path: '/a', redirect: To => {// method receives destination route as argument // return redirected string path/path object}}]})Copy the code
Note: Redirection does not trigger the navigation guard
The alias
Just like people’s nicknames, although the name is different, but you are still you; The same goes for routes, which have different pathnames but still jump to the same component
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
Copy the code
Programmatic routing
Instead of using
to create an A tag to define navigation links, we can use the router instance method to write code to do so.
Note: Inside the Vue instance, you can access the routing instance through $router.
Router object methods
$router.push()
To navigate to different urls, use the router.push method. This method adds a new record to the history stack, so when the user clicks the browser back button, it returns to the previous URL.
Click on the<router-link :to="..." >
Equivalent to callingrouter.push(...)
.
router.push(location, onComplete? , onAbort?)
The argument to this method can be a string path or an object describing the address. Such as:
Router.push ('home') // Object router.push({path: 'home'}) // Named route Router.push ({name: 'user', params: {userId: '123'}}) // change to /register? plan=private router.push({ path: 'register', query: { plan: 'private' }}) const userId = '123' router.push({ name: 'user', params: { userId }}) // -> /user/123 router.push({ path: ` ` / user / ${username}}) / / - > / user / 123 / / params does not effect the router here. Push ({path: '/ user' params: {username}}) / / - > / userCopy the code
$router.replace()
Much like router.push, it does not add a new record to history, but replaces the current history record with its method name.
The usage is the same
$router.go()
This method takes an integer that means how many steps forward or backward in the history, similar to window.history.go(n).
Forward () router.go(1) // Back () router.go(-1)Copy the code
History native method
If you’re already familiar with the Browser History APIs (opens New Window), manipulating History in the Vue Router is super simple.
It is also worth mentioning that the navigation methods of Vue Router (push, replace, go) are consistent in all routing modes (history, Hash, and abstract).
Routing and the cords
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({
routes: [{ path: '/user/:id', component: User }]
})
Copy the code
Using $route in a component makes it highly coupled to its corresponding route, limiting its flexibility by limiting its use to certain urls.
Decoupled by props
const User = { props: ['id'], template: '<div>User {{ id }}</div>' } const router = new VueRouter({ routes: [ { path: '/user/:id', Component: user, props: true}, // For routes that contain named views, you must add 'props' options for each named view: {path: '/user/:id', components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false } } ] })Copy the code
Boolean value
If props is set to true, route.params will be set to the component property.
Object values
If props were an object, it would be set as a component property as is. This is useful when props is static.
The function mode
You can create a function that returns props. This allows you to convert parameters to another type, combine static values with route-based values, and so on.
const router = new VueRouter({
routes: [
{
path: '/search',
component: SearchUser,
props: route => ({ query: route.query.q })
}
]
})
Copy the code
URL /search? Q =vue passes {query: ‘vue’} as an attribute to the SearchUser component.
Routing meta information
When defining a route, you can configure the meta object:
Each route object in the Routes configuration is a route record. Routing records can be nested. Therefore, when a route is matched successfully, it may match multiple routing records.
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
// a meta field
meta: { requiresAuth: true }
}
]
}
]
})
Copy the code
All routing records matched by a route are exposed as $Route objects;
Example: Iterate through the array of routing match fields and look at the META field in the record to determine whether to log in
router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requiresAuth)) { if (! auth.loggedIn()) { next({ path: '/login', query: { redirect: To.fullpath}})} else {next()}} else {next() // Make sure to call next()}})Copy the code
Transition effects
is a basic dynamic component that uses different components to jump to different routes
<! <transition :name="transitionName"> <router-view></router-view> </transition> // then in the parent component // Watch $route Determines which transition watch to use: { '$route' (to, from) { const toDepth = to.path.split('/').length const fromDepth = from.path.split('/').length this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left' } }Copy the code
Navigation guard
Vue-router provides navigation guards that are used to guard navigation by jumping or canceling. There are several opportunities for embedding route navigation: global, single route proprietary, or component level.
Remember that changes in parameters or queries do not trigger entry/exit navigational guards.
You can respond to these changes by observing the $Route object, or by using the beforeRouteUpdate component internal guard.
Global guard
Global front guard
When a navigation is triggered, the global front-guard is called in the order it was created. The guard resolves asynchronously, in which case the navigation waits until all the guards resolve.
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
Copy the code
Example: Often used for user authentication
router.beforeEach((to, from, next) => { if (to.name ! == 'Login' && ! isAuthenticated) next({ name: 'Login' }) else next() })Copy the code
Each guard method takes three arguments:
-
To: indicates the destination route object to be entered
-
From: The route object that the current navigation is leaving
-
Next: Execute the next method, be sure to call that method to resolve the hook; This function can pass arguments:
- Next ()/next(true) : Next hook into the pipe; The navigation state is COMFIRMed after execution
- Next (false) : interrupts the current route; Users can manually click the browser back button to return to the address of from
- Next (‘/’)/next({path: ‘/’}) : jump to a specified address; The next method can pass the same arguments as $router.push()
- next(error): Terminates navigation, error to
router.onError()
Global parsing guard
Register a global guard with router.beforeResolve. This is similar to router.beforeeach, except that the parse guard is called before the navigation is confirmed and after all the intra-component guards and asynchronous routing components are parsed.
Global post-hook
Will not accept the next function or change the navigation itself
router.afterEach((to, from) => {
// ...
})
Copy the code
Route exclusive guard
Define beforeEnter guard directly on route configuration:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
Copy the code
Guards within components
Define the following route navigators directly within the routing component:
●beforeRouteEnter: before the component enters, the component instance is not created (next(VM => {})) ●beforeRouteUpdate: before the component leaves ●beforeRouteLeave: before the component leaves
const Foo = { template: `... ', beforeRouteEnter(to, from, next) {// Call the render component before the corresponding route is confirmed // no! Can!!!! Next (VM => {// access component instance through 'VM'})}, beforeRouteUpdate(to, from, next) {// In the current route change, For example, for a path /foo/:id with dynamic parameters, // will be reused since the same foo component will be rendered when it jumps between /foo/1 and /foo/2. And the hook will be called in that case. // Call beforeRouteLeave(to, from, next) {// Call beforeRouteLeave(to, from, next) {Copy the code
Data request
After entering a route, you need to obtain data from the server. For example, when rendering user information, you need to fetch user data from the server. We can do this in two ways:
- Retrieves after navigation: Completes navigation, then retrieves data in the following component lifecycle hooks. Display instructions such as “loading” during data retrieval.
- Before the completion of navigation: Before the completion of navigation, data is obtained from the guard entering the route, and navigation is performed after the data is obtained successfully.
Get the data after navigation is complete
Display one loading state during data acquisition, and display different loading states between different views.
Created () {// Data is observed after the component is created, watch: {if the route changes, the method '$route' is executed again: 'fetchData' },Copy the code
Get data before navigation is complete
BeforeRouteEnter (to, from, next) {getPost(to.params.id, () => {next(vm => vm.fetchData())})}, BeforeRouteUpdate (to, from, next) {this.post = null getPost(to.params.id, () => { this.fetchData() next() }) },Copy the code
Scrolling behavior
When switching to a new path, you want the page to roll to the top, or to keep the original scrolling position, as if the page had been reloaded. Vue-router can do this, and better, by letting you customize how the page scrolls when switching routes.
Note: This feature is only available in browsers that support history.pushState.
To create a Router instance, you can provide a scrollBehavior method:
const router = new VueRouter({ routes: [...] , scrollBehavior (to, from, SavedPosition) {if (savedPosition) {return savedPosition} else {return {x: 0, y: 0}}}})Copy the code
The scrollBehavior method receives to and FROM routing objects. The third parameter savedPosition is available if and only if popState navigation (triggered by the browser’s forward/back buttons).
This method returns information about an object at the scroll position, which looks like this:
{ x: number, y: number }
{ selector: string, offset? : { x: number, y: number }}
Route lazy loading
JavaScript packages can become very large when packaged to build applications, affecting page loads. It would be much more efficient if we could split the components corresponding to different routes into different code blocks and then load the components only when the routes are accessed.
const Foo = () => import( './Foo.vue')
const Bar = () => import( './Bar.vue')
const Baz = () => import('./Baz.vue')
Copy the code