基础
路由规划配置,router/index.js
const routes = [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/admin',
name: 'admin',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "admin" */ '../views/Admin.vue'),
},
];
路由出口导航,App.vue
<div id="app">
<nav>
<router-link to="/">home</router-link>
<router-link to="/admin">admin</router-link>
</nav>
<router-view></router-view>
</div>
动态路由
路由配置
// router/index.js
{
path: '/course/:name',
component: () => import(/* webpackChunkName: "course" */ '../views/Detail.vue'),
}
路由跳转
<router-link :to="`/course/${c.name}`">
{{ c.name }} - {{ c.price | currency('¥') }}
</router-link>
参数读取
<p>{{$route.params.name}}</p>
通配符
// router/index.js
{
path: '*',
component: () => import('../views/404.vue'),
}
嵌套路由
// router/index.js
{
path: '/admin',
name: 'admin',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "admin" */ '../views/Admin.vue'),
children: [
{
path: '/admin/course/:name',
name: 'course',
component: () => import(/* webpackChunkName: "course" */ '../views/Detail.vue'),
},
],
}
使用
<div class="admin">
<img alt="Vue logo" src="../assets/logo.png">
<a href="">test</a>
<course-list :courses="courses"></course-list>
<router-view></router-view>
</div>
组件复用注意事项
组件复用时嵌套,局部组件更新时,容器create不动,可以通过监听$route变化实现
export default {
watch: {
$route: {
handler: () => {
console.log('$route change');
},
immediate: true,
}
},
};
编程导航
// router.push(location, onComplete?, onAbort?);
// 字符串
router.push('home');
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' } })
// 带参数查询 => /register?plan=private
router.push({ path: 'register', query: { plan: 'private' } })
路由守卫
全局守卫
// router/index.js // 全局守卫 router.beforeEach((to, from, next) => { // ... // to: Route 即将要进入的目标 路由对象 // from: Route 当前导航正要离开的路由 // next: Function 一定要调用该方法来 resolve 该钩子 });
示例
// 全局守卫 const routes = [ { path: '/admin', name: 'admin', meta: { auth: true, } } ] router.beforeEach((to, from, next) => { if (to.meta.auth) { if (window.isLogin) { next(); } else { next(`/login?redirect=${to.fullPath}`); } } else { next(); } });
路由独享守卫
{ path: '/admin', name: 'admin', // 全局守卫 beforeEnter(to, from, next) => { if (window.isLogin) { next(); } else { next(`/login?redirect=${to.fullPath}`); } } }
组件内守卫
可以在路由组件内直接定义一下路由导航守卫- beforeRouteEnter
- beforeRouteUpdate
- beforeRouteLeave
// Admin.vue beforeRouteEnter(to, from, next) { if (window.isLogin) { next(); } else { next(`/login?redirect=${to.fullPath}`); } }
数据获取时机
路由导航前
// 组件未渲染,通过next传递回调访问组件实例 beforeRouteEnter(to, from, next) { getPost(to.params.id, post => { next(vm => vm.setData(post)); }); } // 组件已渲染,可以访问this直接赋值 beforeRouteUpdate(to, from, next) { this.post = null; getPost(to.params.id, post => { this.setData(post); next(); }) }
路由导航后
created() { this.fetchData(); }, watch: { '$route': 'fetchData', }
addRoutes动态路由
// 动态添加路由
this.$router.addRoutes([
{
path: '/admin',
name: 'admin',
// ...
}]);
组件缓存
利用keep-alive做组件缓存,保留组件状态,提高执行效率
<keep-alive :include="['admin']" max="10">
<router-view></router-view>
</keep-alive>
使用include 或 exclude时使用的是组件的name有两个可利用的钩子:activated、deactivated
路由懒加载
路由组件的懒加载能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应的组件
() => import(/* webpackChunkName: "group-about" */ "../views/About.vue")