路由
https://router.vuejs.org/zh-cn/advanced/navigation-guards.html
// 将路由加入全局。当然你也可以使用 this.$router 来调用实例 window.router = router;
//跳转 router.push("bar")
//配置路由参数 {path:'/order/:id',component:require('./views/orderDetails')}
//在<template>中获取参数 {{$route.params.id}}
//在script中获取参数 console.log(this.$route.params.id)
router.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
/* 配置路由规则 */
const map = [
// 重定向
{path:'/index',redirect: '/'},
// 路由根路径
{path:'/',component:require('./views/index'),
// 定义子路由
children:[
{path:'/order',component:require('./views/order')},
{path:'/card',component:require('./views/card')},
{path:'/add',component:require('./views/add')},
{path:'/form',component:require('./views/form')},
{path:'/repay',component:require('./views/repay')},
{path:'/protocol',component:require('./views/protocol')}
]
},
// 正常路由
{path:'/order/:id',component:require('./views/orderDetails')}
]
/* 实例化路由 */
const router = new VueRouter({
routes : map
})
router.afterEach((to, from) => {
//console.log(to, from)
})
export default router;
main.js
import Vue from 'vue'
import router from './router' //路由相关
window.router = router; //路由文件
const app = new Vue({ router }).$mount('#app')
根目录index.html,添加一个div#app 标签。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vue-test</title>
</head>
<style>
body,html{margin:0;padding:0;}
</style>
<body>
<div id="app">
<transition name="fade">
<router-view ></router-view>
</transition>
</div>
</body>
</html>
index.vue 演示子路由
<template>
<div class="hello container">
<nav-header :_title="mytitle" :left="false"></nav-header>
<div class="mui-content">
<router-link to="order">order</router-link>
<transition name="fade">
<router-view keep-alive></router-view>
</transition>
</div>
</div>
</template>
扩展:演示懒加载路由
http://router.vuejs.org/zh-cn/advanced/lazy-loading.html
const Foo = resolve => require(['./Foo.vue'], resolve) const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ] })
扩展:组件中的路由钩子
beforeRouteEnter (to, from, next) { next(vm => { vm.backPath = from.path }) } beforeRouteLeave (to, from, next) { window.clearInterval(this.getMaxTimer); next(); },
扩展:在默认的情况下当<router-link>对应的路由匹配成时,就会自动设置class属性值为.router-link-active,当然可以自定义自己喜欢的类名,比如fuck-active
常见的使用场景是在网页底部的tab-tag中。
<router-link :to="{name: 'Home'}" tag='li' active-class='fuck-active'> <div><img src="../assets/images/home.png"></div> <div>首页</div> </router-link> # 但每个tab-tag都写上就不够DRY了。有一个技巧是在VueRouter的全局配置中书写,但请斟酌: const router = new VueRouter({ // ...other prototype linkActiveClass: 'fuck-active' })
路由可选参数的坑:
# 如果该参数是动态的数值,直接加入‘?’即可 /houseBusinessDetails/:id? # 但如果是固定的数值,则需要加入()?才可以 /houseBusinessDetails/(id)?/:id?
# 正则表达式加可选参数
/myBusiness/:tag([0-2]?)
让路由与状态融合的插件:vuex-router-sync
import { sync } from 'vuex-router-sync' import router from './router' sync(store, router)
把 vue-router
的狀態放進 vuex
的 state
中,這樣就可以透過改變 state
來進行路由的一些操作
import * as type from './mutation-types.js' const mutations = { [type.IS_LOADING] (state, b) { console.log(state.route) // 打印出路由的实例,那么我们就可以通过它来改变路由地址,为所欲为了 state.is_loading = b; } } export default mutations;
常用的组件内的路由钩子
beforeRouteEnter (to, from, next) { next(vm => { if (from.path === '/myBusiness') vm.$router.push('/') next() }) }
路由使用
// 路由超链接 ,注意这个to,如果是纯字符串的时候直接to="xxxx",如果是变量的时候再使用:to <router-link :to=backPath :class=backPath ></router-link> //加入全局变量,这样才能在其他地方调用 window.router = router //跳转 router.push("bar") //可以使用afterEach + vuex 来实现动态获取后退页面的地址 router.afterEach((to, from) => { console.log(to, from) }) //可以使用beforeEach 来拦截页面 并且进行一些操作之后再放行next() router.beforeEach((to,from,next) => { console.log(to,from); next(); //放行 }) //children子路由,当我们在order页面中加入 <router-view> 时,orderDetails 页面 会从该 <router-view> 中进出 { path:'/order',component:require('./views/order'), children:[ {path:':id',component:require('./views/orderDetails')} ] } /* 再来一个子路由的demo: 上面的demo中,不知为何?如果直接写上:id ,会直接将子路由配置的页面显示在父页面中。 所以我换成这个demo的就可以了。只有等我点击才出现在父页面. */ {path:'/astro',component:require('./views/astro/index'),children:[{path:'/astro/:consName',component:require('./views/astro/info')}]} // 监听路由页面进入事件 beforeRouteEnter:(to, from, next) => { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当钩子执行前,组件实例还没被创建 next( vm => { vm.$parent.route_pipe(true); }); }, // 监听路由页面的退出事件 beforeRouteLeave (to, from, next) { console.log(this); next(); }, //如果两个页面都是通过同一个 <router-view> 进出,那么他们的动画事件(enter/leave)会同时触发,尽管某些场景下能实现华丽的效果。 //但某些场景你不想被混淆,譬如层层嵌套的界面:index->order->orderDetails.类似这种页面结构,应该使用嵌套路由 + chilren路由配置,参考上面的子路由demo