Vue - router
Vue Router 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们。
router/index.js:有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:路由定义得越早,优先级就越高。
有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes
配置中给某个路由设置名称。定义路由的时候可以配置 meta
字段:
“重定向”的意思是,当用户访问 /a
时,URL 将会被替换成 /b
,然后匹配路由为 /b
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) /* Layout */ import Layout from '@/layout' // 公共路由 export const constantRoutes = [ { path: '/login', component: () => import('@/views/login'), hidden: true }, { path: '/register', component: () => import('@/views/register'), hidden: true }, { path: '/404', component: () => import('@/views/error/404'), hidden: true }, { path: '/401', component: () => import('@/views/error/401'), hidden: true }, { path: '', component: Layout, redirect: 'index', children: [ { path: 'index', component: () => import('@/views/index'), name: '首页', meta: { title: '首页', icon: 'dashboard', noCache: true, affix: true } } ] } ] export default new Router({ mode: 'history', // 去掉url中的# scrollBehavior: () => ({ y: 0 }), routes: constantRoutes })
main.js 挂载到根实例:
import router from './router' new Vue({ // el: '#app', router, store, render: h => h(App) }).$mount('#app')
通过注入路由器,我们可以在任何组件内通过 this.$router
访问路由器,也可以通过 this.$route
访问当前路由:
// Home.vue export default { computed: { username() { return this.$route.params.username } }, methods: { goBack() { window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/') } } }
留意一下 this.$router
和 router
使用起来完全一样。我们使用 this.$router
的原因是我们并不想在每个独立需要封装路由的组件中都导入路由。
动态路由:
当使用路由参数时,例如从 /user/foo
导航到 /user/bar
,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route
对象:
const User = { template: '...', watch: { $route(to, from) { // 对路由变化作出响应... } } }
嵌套路由:
router-view和children 同时出现
const User = { template: ` <div class="user"> <h2>User {{ $route.params.id }}</h2> <router-view></router-view> </div> ` } ...... const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ { // 当 /user/:id/profile 匹配成功, // UserProfile 会被渲染在 User 的 <router-view> 中 path: 'profile', component: UserProfile }, { // 当 /user/:id/posts 匹配成功 // UserPosts 会被渲染在 User 的 <router-view> 中 path: 'posts', component: UserPosts } ] } ] })
基于上面的配置,当你访问 /user/foo
时,User
的出口是不会渲染任何东西,这是因为没有匹配到合适的子路由。如果你想要渲染点什么,可以提供一个 空的 子路由:
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ // 当 /user/:id 匹配成功, // UserHome 会被渲染在 User 的 <router-view> 中 { path: '', component: UserHome } // ...其他子路由 ] } ] })
编程导航:
// 字符串 router.push('home') // 对象 router.push({ path: 'home' }) // 命名的路由 router.push({ name: 'user', params: { userId: '123' }}) // 带查询参数,变成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }})
// 在浏览器记录中前进一步,等同于 history.forward() router.go(1) // 后退一步记录,等同于 history.back() router.go(-1) // 前进 3 步记录 router.go(3) // 如果 history 记录不够用,那就默默地失败呗 router.go(-100) router.go(100)
导航守卫:
记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route
对象来应对这些变化。
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })
确保 next
函数在任何给定的导航守卫中都被严格调用一次
// GOOD router.beforeEach((to, from, next) => { if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' }) else next() })
实例:
对于下面的路由效果,访问网址时匹配到如下路由,到layout组件(里面有router-view),又重向到 /index
{ path: '', component: Layout, redirect: 'index', children: [ { path: 'index', component: (resolve) => require(['@/views/index'], resolve), name: 'Index', meta: { title: '首页', icon: 'dashboard', affix: true } } ] }
注意嵌套路由渲染效果,每个组件都有一个$route对象。
下图为 系统管理-用户管理组件 ,深刻理解一下路由是平级的:即每次路由变化都需要重新匹配规则,类似于无状态
下图为 history : route.go(-1) from to:
posted on 2021-12-30 20:04 TrustNature 阅读(61) 评论(0) 编辑 收藏 举报