vue路由绝对是vue中的一大块,基本上路由都有两大模式history模式和hash模式,而我们常用的则是history模式
-
vue-router
默认的路由使用的hash模式 (http://localhost:8080/#/page1)
-
起步 :安装vue-router模块
npm install vue-router --save
-
新建router.js进行路由配置
import VueRouter from 'vue-router'; import Page1 from './components/Page1'; import Page2 from './components/Page2'; export default new VueRouter({ routes:[ {path:'/page1',component:Page1}, {path:'/page2',component:Page2}, ] })
-
在main.js中进行使用插件,赋予vue控制路由的能力
import VueRouter from 'vue-router'; import router from './routes'; Vue.use(VueRouter); //将this.$router 挂载到原型链上,使得vue具有处理路由的能力 new Vue({ router, render: h => h(App), }).$mount('#app');
-
在App.vue中使用 ,使用router-view 标签进行占位
<!--路由占位符--> <router-view></router-view>
-
按钮导航,
<router-link to="/page1" class="page1">页面1</router-link> <router-link to="/page2" class="page2">页面2</router-link>
history模式:
默认是hash 模式的路由,url 使用#后面定位路由,对SEO不利,设置history模式可以使用普通的url
//直接在routes.js中配置 mode: export default new VueRouter({ mode:"history", routes:[ {path:'/page1',component:Page1}, {path:'/page2',component:Page2}, ] })
动态路由:
在配置路由的使用:id占位符,和angualar类似 ,一些参数可以使用this.$route.XX进行获取
export default new VueRouter({ mode:"history", routes:[ {path:'/page1',component:Page1}, {path:'/page2',component:Page2}, {path:'/page3/:id',component:Page3}, ] }) // ---------进行获取 computed:{ name(){ return this.$route.params.id } }
这种获取路由参数比较麻烦,更优雅的方式获取,使用属性传递的方式进行获取
export default new VueRouter({ mode:"history", routes:[ {path:'/page1',component:Page1}, {path:'/page2',component:Page2}, {path:'/page3/:id',props:true,component:Page3}, // 使用props 表示属性传递 ] }) //-------在进行或去就比较优雅 ,直接使用props接收 props:['id'],
子路由嵌套
export default new VueRouter({ mode:"history", routes:[ {path:'/login',component:Login}, { path:'/dashboard', component:DashBoard, children:[ //---------子路由的嵌套 {path:'/page1',component:Page1}, {path:'/page2',component:Page2}, {path:'/page3/:id',props:true,component:Page3}, ] }, ] }) //-------------第一层使用 <div id="app"> <h1>2019年,新的一天你好!!!</h1> <hr> //路由占位符 <router-view></router-view> <!--第一层,包含login和dashboard两个路由--> </div> //------------dashboard里边的嵌套 <template> <div> <div class="navbar"> <router-link to="/page1" class="page1">页面1</router-link> <router-link to="/page2" class="page2">页面2</router-link> <router-link to="/page3/vuejs" class="page2">Vue</router-link> </div> <hr> <router-view></router-view> <!--这是第二层,子路由嵌套在这里--> </div> </template>
路由的重定向:使用redirect进行重定向
{path:'/',redirect:'/login'},
路由守卫 :(在路由跳转之前或者路由跳转之后hooks)钩子
let let routes = new VueRouter({ ... }) routes.beforeEach((to, from, next) => { console.log('beforeEach',to); // to 是和那个路由里的所有东西 if (to.path!=='/login'){ //逻辑是如果不是login页面则随便跳转 ,但是如果是login页面则需要两秒之后跳转 next() }else{ setTimeout(()=>{ next(); },2000) } }); routes.afterEach((to,from)=>{ console.log('afterEach'); }); export default routes
组件内部生命周期:上边的路由守卫是全局的 ,我们组件内部也有一些内部生命周期
需要一些组件内部的守卫 ,有两种方法
-
在routes配置path的时候进行,不推荐
export default new VueRouter({ routes:[ {path:'/page1',component:Page1}, {path:'/page2',component:Page2}, ] })
-
再组件内部 执行 推荐
注意顺序是 ,路由守卫beforeEach ->beforeRouteEnter ->beforeRouteLeave->afterEach的顺序
<script> export default { beforeRouteEnter(to,from,next){ console.log('page3进来了'); next(); }, beforeRouteLeave(to,from,next){ console.log('page3准备退出了'); if (window.confirm('您真的要退出么?')){ next(); } }, } </script>
-
当路由组件没有变但是路由的参数变了时,比如 由 page3/vuejs变为 page3/react
beforeRouteUpdate(to,form,next){ console.log('page3路由,但是参数变化了'); next(); },
整个路由的操作逻辑 ,我理解是执行顺序
- 导航被触发
- 调用全局的beforeEach守卫
- 在重用的组件里调用beforeRouteUpdate守卫
- 在路由配置里边调用beforeEnter 这个和组件里的beforeRouteEnter类似
- 在被激活的组件⾥调⽤ beforeRouteEnter。
- 调⽤全局的 beforeResolve 守卫 (2.5+)。 这个比全局的beforeEach守卫晚一点点
- 导航被确认。
- 组件的beforeRouteLeave
- 调用全局的 afterEach 钩子。
- 触发 DOM 更新。
异步组件 ,懒加载
路由懒加载vue中配合webpack非常简单 ,在需要懒加载的组件的路由配置中直接import()
//比如让login组件实现懒加载 {path:'/login',component:()=>import('./components/Login')} //{path:'/login',component:Login},
-