路由是根据不同的url地址展现不同的内容或页面。
前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做(在单页面应用,大部分页面结构不变,只改变部分内容的使用),之前是通过服务器根据url的不同返回不同的页面。
前端路由优点:用户体验好,不需要每次都从服务器全部获取,快速展现给用户
缺点:不利于SEO,使用浏览器的前进后退会重新发送请求,没有合理地利用缓存,无法记住之前的滚动条
- vue-router用来构建SPA(单页面应用)
<router-link></router-link>或者this.$router.push({path:""})路由跳转的链接<router-view></router-view>
vue-router就是对history的封装
获取地址参数
$route.params.id 命名的路由,'/goods/:id'
$route.query.id 带查询参数带查询参数,'/goods?id=123'
动态路由
1export default new Router({ 2 mode:'history',//路由模式。默认是hash,地址后面跟#;history是主流方式,更加真实 3 saveScrollPosition:true,//保存滚动条位置 4 routes: [ 5 { 6 path: '/goods/:id/user/:name', 7 name: 'Hello', 8 component: GoodList 9 } 10 ] 11}) 12 13 <p>{{$route.params.id}}</p> 14 <p>{{$route.params.name}}</p>
路由嵌套
1routes: [ 2 { 3 path: '/goods', 4 name: 'GoodList', 5 component: GoodList, 6 children:[ 7 { 8 // 当 /goods/title匹配成功 9 // Title 会被渲染在 GoodList 的 <router-view> 中 10 path:'title',//不需要/ 11 component:Title 12 }, 13 { 14 path:'image', 15 component:Image 16 } 17 ] 18 } 19 ] 20 21<router-link to="/goods/title">显示标题</router-link><!-- 链接到一个路由 --> 22<router-link to="/goods/image">显示图片</router-link> 23<router-view></router-view>
编程式路由
通过js来实现页面的跳转
1// 字符串 2$router.push('name') 3//对象 4$router.push({path:'name'}) 5//命名的路由 6$router.push({ name: 'user', params: { userId: 123 }}) 7//带查询参数,变成 /name?a=123 8$router.push({path:'name?a=123'}) 或者 $router.push({path:'name',query:'a=123'}) 9 10$router.go('-1') 相当于history()
如果提供了 path,params 会被忽略
1const userId = 123 2router.push({ name: 'user', params: { userId }}) // -> /user/123 3router.push({ path: `/user/${userId}` }) // -> /user/123 4// 这里的 params 不生效 5router.push({ path: '/user', params: { userId }})
命名视图
1<router-view></router-view> 2<router-view name="a"></router-view> 3<router-view name="b"></router-view> 4 5const router = new VueRouter({ 6 routes: [ 7 { 8 path: '/', 9 components: { 10 default: Foo, 11 a: Bar, 12 b: Baz 13 } 14 } 15 ] 16})
路由懒加载
1//import Home from '@/page/home' 2const Home = resolve => require(['@/page/Home'], resolve) 3 4routes: [ 5 { 6 path: '/', 7 components:Home, 8 } 9] 10 11component: (resolve) => { 12 require(['@/views/Cart'], resolve) 13}
路由拦截
1const router = new Router({ 2 mode: 'history', 3 routes: [ 4 { 5 path: '/cart', 6 name: 'Cart', 7 // 需要登录才能进入的页面可以增加一个meta属性 8 meta: {//路由元信息 9 requireAuth: true 10 }, 11 component: (resolve) => { 12 require(['@/views/Cart'], resolve) 13 } 14 }, 15 ] 16}) 17 18// 判断是否需要登录权限 以及是否登录 19router.beforeEach((to, from, next) => {//全局守卫 20 if (to.matched.some(record => record.meta.requireAuth)) {// 判断是否需要登录权限 21 if (router.app.$options.store.state.nickName!=='') {// 判断是否登录,在server/app.js设置了全局拦截,未登录status=1001 22 next() 23 } else {// 没登录则跳转到登录界面 24 next({ 25 path: '/', 26 query: {redirect: to.fullPath}//?redirect=%2Fcart 27 }) 28 router.app.$options.store.commit('updataLoginModalFlag',true); 29 } 30 } else { 31 next() 32 } 33})
动态添加路由
1indexUrl='/service-center'; 2router.addRoutes([{ 3 path: '/', 4 redirect: indexUrl, 5 name:'Index' 6}])