vue-router 学习整理

概述

vue-router是vue-cli中管理路由的模块
通过URL,实现URL和组件之间的一一对应,通过URL进行组件 切换

应用场景:
单页面应用 single page application(SPA) 移动端应用很广泛, 没有真实的页面跳转,只是针对不用URL在页面内容区域做了不同的渲染
只是加载一次JS、CSS文件,降低了页面切换时候的 HTTP请求

安装方式

1.一般在vue-cli初始化(vue init webpack 项目名称)时候,会有提示 是否安装vue-router,选择y回车,即可安装
2.后续手动安装,命令行到指定目录
输入:

npm install vue-router --save   //安装vue-router并添加到依赖
使用

以将代码放置在入口文件main.js为例

import Vue from 'vue'
import App from './app'
//1.引入模块
import VueRouter from 'vue-router' 

//2.将vue-router作为Vue的插件
Vue.use(VueRouter)

//3.创建vue-router实例
let router = new VueRouter({
  ...
})

//4.将路由配置信息router挂载到Vue实例
new Vue({
  el: '#app',
  router,  
  template: ''
  components:{
    App    //App为跟组件 App.vue 
  }
})
配置路由

let router = new VueRouter({ ... })
说明:为什么命名router
router是我们的路由实例,命名为变量router是为了方便简写,在Vue实例上有个键名叫router,两者相同则可以写一个键名即可

1.简单配置路由

new VueRouter({
  mode:'history',  //模式分为 hash,history两种,默认为hash
  linkActiveClass:'xxx', //当前处在激活状态下的router-link标签上的状态class名
  scrollBehavior(to,from,saveposition){   //滑动信息 
    ...
  },
  routes:[  //路由调整信息
    {
      path:'/',  //这个是路径
      component:xxx,  //这个是对应import过来的单文件组件,作为模板
      alias:'/index',  //访问另一个路径,扔可以访问,但是不会触发按钮的激活类名
      name:'indexpage' ,
      meta:{      //定义针对当前路由的自定义数据
        needlogin:true
      }
   },{
      path:'/about',
      component:xxx
    },{
      path:'*',    //通配符,标识没有配置路由的路径情况,一般作为404
      redirect:{    //重新定向到一个已经存在的路由路径
        path:'xxxx'  
      }
    }
  ]
})

另外,配置路由,引入模板时候,在vue-cli中 @标识src文件夹,可以在webpack.base.conf.js 查看其声明

2.关于配置路由中的mode选择

new VueRouter({
  mode:'hash',    //如果选择hash模式,链接中需要带#
  routes:[
    ...
  ]
})

建议:
一般低版本浏览器使用hash模式
高版本浏览器使用history模式

3.关于配置路由中的重定向redirect

  redirect((to)=>{      //通过箭头函数,参数to,可以获取path路径,可以更加丰富我们重定向的逻辑
    if(to.path=='xxx'){
      return '/my';  //跳转到我的
    }else{
      return '/';  //跳转到首页
    }
  })

  //redirect书写的方式
  redirect:'/about'
  redirect:{path:'/about'}
  redirect:{name:'xxx'} //通过routes中的name,也可以定位 

4.存在二级路径嵌套时候
默认显示第一项的需求
在二级嵌套中,如果希望父路由默认显示第一个子路由信息,且子路由为激活状态
则可以将父路由path:'',将子路由的第一项path设置为父路由原有path

  ...
  {
    path: '/about',
    component: 'xxx',
    children:[
      {
        path:'/about/xxx',    //二级子菜单
        component:'xxxx'
      }
    ]
  }
  ...

使用children嵌套数据,将子路由对象放进去

5.路由是我们配置浏览器跳转的基本配置,在模板页面中我们需要使用连接来触发

我是个按钮

router-link属性:
to="xxx" //相当于a标签的href,填写跳转链接
tag="li"  //将渲染为什么标签,以便浏览器去渲染
event="hover" //如果要添加一个触发事件,则用event来声明,默认click
active-class="xxx"  
//如果标签对应的,路由路径为当前状态,则vue-router会默认为其添加激活的状态类名
//如果你想自定义自己的激活状态class名,则用这个
//另外,自定义状态类名有2个位置,一个在路由配置中,一个在这个触发按钮上,
//同时配置,按钮的优先级高,会剔除掉路由上的激活状态配置类名

exact 
//如果不采用相对于根路径 /xxx  那么有可能存在,父路由,子路由同时处于激活class名状态下
//此时,添加exact 严格模式,以便只有一个路由显示激活class名      

6.对应path有router-link,对应的component,应该渲染到这里


  按钮1    //如果router-link要嵌套a标签,则a标签不用再写href了


  按钮2

//多个按钮对应一个router-view

7.命名视图
在路由配置的routes中 path和component是一一对应的,
如果我们希望某一个path对应多个component时候
如:

//在路由配置文件中
  path:"/about",
  components:{    //注意 components 是复数形式
    default: "模板1",  //不写name的view-router为default
    slider: "模板2"  
  }

//在单文件组件中
//当我们访问 /about 时候,下面2个router-view会同时显示



//在router-view中可以添加class名,
  //router-view中的所有结构都有一个父级class名为father-box

//在单文件组件中


//渲染后
//类名会进行合并

hello

8.路由配置中的scrollBehavior
在页面onload或者浏览器前进,后退时候触发

scrollBehavior(to,from,saveposition ){
   //to 目标路由
   //from 当前路由
   //saveposition 当前位置
   //可以将当前  saveposition 作为返回值,达到页面跳转,返回后恢复滚动条位置的效果

   //滚动条滑动顶部位置
   return { x: 0, y: 0 };
}

8.动态路由
在路由配置中,所有的path都是以一个可预测的状态存在
如果我们希望添加一个格式,不清楚具体数据,需要使用动态路由

  //在路由配置中  
  ...
  {
    path:'/students/:userId?',  //其可以匹配 /students,/students/1,/students/2
    component:'xxx'
  }  
  ...
  
  //在单文件组件页面
  通过 this.$route.params.userId 可以获取其信息,使得后续逻辑上更加丰富

9.路由的自定义属性

  ...
  {
    path:'xxxx',
    component:'xxxx',
    meta:{
      needlogin:true
    }
  }
  ...

  //在单文件组件中,我们可以通过$route中获取
  this.$route.meta.needlogin
  1. 动态路由的传参的新方式,配置props: true
  • 通常方式
//---路由部分
routes:[
  {
    path:'/categories/edit/:id?' 
    component:'xxx'
  }
]
//---单文件组件中
created(){
   console.log(this.$route.params.id);
}
  • 新的传递params方式:
    路由中props为true,代表将连接中任何参数,以props方式注入到新组件中去
//---路由部分
routes:[
  {
    path:'/categories/edit/:id?' 
    component:'xxx',
    props: true
  }
]
//---单文件组件中
props:[
  'id'
]
router 与 $route

router是我们创建的VueRouter实例
$route是当前单文件组件的路由实例

router实例方法 实现 【编程式导航】

//直接跳转
router.push('/about')
router.push({ path: '/about' })

//动态路由,单文件页面通过 this.$route.params.userId 获取传递信息
router.push({ name: 'about', params: { userId: '123' }})

//查询字符串方式,用户访问有权限的页面,直接跳转到登录页,
//登录完成后,通过this.$route.query.redirect 获取用户之前想去的页面,然后通过push,再次跳转
//实现 未登录状态->登录->登录后自动跳转用户之前想去的 权限限制页面
router.push({ path: '/login', query: { redirect: '/user' }})

其他方法:

  router.repalce( '/xxx' ) 
//将历史记录中的当前步骤替换掉,并且完成跳转

  router.go(number)  
  // 填写具体数字,针对history的当前步数,向前是负值,向后是正值,但是只能在历史步数内,超过则不作操作

vue-router生命周期 钩子

全局钩子函数

所有路由进入,出去都会触发此钩子函数

  1. beforeEach
    还没有进入路由内,所有不能获取vue实例
    如果此时此刻想获取,可以通过router.app方式,得到vue实例
let router = new VueRouter({...})

router.beforeEach(function(to,from,next){
    console.log(to); //目标导航
    console.log(from);  //离开导航
    next(); //执行则路由跳转

    //实际例子,根据路由情况,判断是否需要登录
    //根据目标路径下的 自定义属性meta(如果你设置了),如 
    ...
    {
        path:'/xxx'
        component:'xxx',
        meta:{              //meta提供开发者挂载自定义数据
            needLogin:true      //xxx页面需要登录
        }
    }
    ...

    //如果跳转到xxx页面,则跳转到登录/login,否则路由正常跳转
    if(to.meta.needLogin){
        next('/login');
    }else{
        next();
    }

})
  1. afterEach
rourer.afterEach(function(to,from){
    //路由跳转后,我们可以做一些操作
    //例如: 根据path或者meta添加新属性,去判断,改变文档标题

    if(to.path=='/'){
        window.document.title = 'xxx'
    }else if{
        ...
    }else{
        ...
    }
});

局部钩子函数

beforeEnter 针对某一个路由,进行处理

  ...,
  {
    path:'xxx'
    component:'xxx',
    beforeEnter(to,from,next){
        //只是针对xxx这个path,做操作
        next();  //next必须执行,否则会卡住
    }   
  },
  ...
单文件组件中的钩子函数
优先顺序从【0】开始


路由的细节问题

  1. 同一个路由地址,query参数不同,点击通过$router.push从当前路由地址,跳转到当前路由地址,参数变化
//传值
this.$router.push({path:"/menLink",query:{alert:"页面跳转成功"}})
//用query获取值

提示:{{this.$route.query.alert}}

页面不重新渲染的情况,只需要对 增加属性key

 

1-2. 当两个不同的path,对应相同的component的时候;
在两个路由之间切换,不会改变router-view视图更新
如:

{
  path: '/create',
  component:Categories
},{
  path: '/edit/:id',
  component:Categories
}

解决方法:
绑定key属性


1-3.当两个相同的path,对应相同的component的时候;
在两个路由之间切换,不会触发created的生命周期函数,不会对router-view进行视图更新
如:

{
  path: '/article/:id',
  component:Article
}

id=1 与 id=2 两个情况,切换时候碰到
解决方法:
需要针对id进行watch,之后强制触发created中的数据获取函数
如:

watch:{
  id : function(){
    //请求对应ID下的数据,进行视图渲染
    this.getDataByIdFn();
  }
},
created(){
  //默认进入获取
  this.getDataByIdFn();
}
  1. ios 和 safari下,相同path但query修改,跳转后,会出现页面不渲染的情况,因此使用window.location.reload刷新页面
this.$router
.push({ path: "/college", query: { DeptInfo: id } })
.then(() => {
    window.location.reload();
});

生命周期相关

组件内路由

  • beforeRouteEnter
beforeRouteEnter(to, from, next){
    // 无法获取this,只能通过vm获取
    next(vm => {
      vm.routeFrom = from.name
      vm.routeTo = to.name
    })
}
  • beforeRouteLeave
beforeRouteLeave(to, from, next){
    this.routeFrom = from.name
    this.routeTo = to.name
}

你可能感兴趣的:(vue-router 学习整理)