16.编程式路由
16.1.利用JS实现路由跳转
router-link标签可以实现页面超链接形式的路由跳转。但是实际开发中,在很多情况下,需要通过某些逻辑判断来确定如何进行路由跳转。也就是说:需要在js代码中进行路由跳转。此时可以使用编程式路由。
- 使用this.$router.push方法可以实现路由跳转,方法的第一个参数可为string类型的路径,或者可以通过对象将相应参数传入。
- 通过this.$router.go(n)方法可以实现路由的前进后退,n表示跳转的个数,正数表示前进,负数表示后退。
- 如果只想实现前进后退可以使用this.$router.forward()(前进一页),以及this.$router.back()(后退一页)。
html
<div id="app">
<p>
<button @click="toHome">首页</button>
<button @click="toNews">新闻</button>
<button @click="toLogin">登陆</button>
<button @click="doForward1">前进</button>
<button @click="doForward2">前进</button>
<button @click="doBack1">后退</button>
<button @click="doBack2">后退</button>
</p>
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
const Home = {
template: '<div>首页</div>'
}
const News = {
template: '<div>新闻:</div>'
}
const Login = {
template: '<div>登陆</div>'
}
const routes = [{
path: '/',
component: Home
}, {
path: '/home',
component: Home
}, {
path: '/news',
component: News
}, {
path: '/login',
component: Login
}]
const router = new VueRouter({
routes
})
var vm = new Vue({
el: '#app',
data: {},
router,
methods:{
toHome(){
//无参数时,push方法中直接写路由地址
this.$router.push('/home');
},
toNews(){
//有参数时,push方法中写一个json对象
this.$router.push({path:'/news',query:{name:'zhangsan'}});
},
toLogin(){
this.$router.push('/login');
},
doForward1(){
this.$router.forward();
},
doForward2(){
this.$router.go(1);
},
doBack1(){
this.$router.back();
},
doBack2(){
this.$router.go(-1);
}
}
})
</script>
16.2.通过watch实现路由监听
通过watch属性设置监听$route变化,达到监听路由跳转的目的。
在上面代码中添加watch监听:
javascript
watch: {
// 监听路由跳转。
$route(newRoute, oldRoute) {
console.log('watch', newRoute, oldRoute)
}
}
16.3.导航守卫
路由跳转前做一些验证,比如登录验证,是网站中的普遍需求。 对此,vue-route 提供了实现导航守卫(navigation-guards)的功能。
你可以使用 router.beforeEach 注册一个全局前置守卫:
javascript
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
每个守卫方法接收三个参数:
- to:即将要进入的目标路由对象(去哪里),可以使用 to.path 获取即将要进入路由地址。
- from:当前导航正要离开的路由对象(从哪来),可以使用 from.path 获取正要离开的路由地址。
- next:一个函数,表示继续执行下一个路由。(如果没有next,将不会进入到下一个路由)
下面例子中实现了如下功能:
- 列举需要判断登录状态的 “路由集合”,当跳转至集合中的路由时,如果“未登录状态”,则跳转到登录页面
- 当直接进入登录页面LoginPage时,如果“已登录状态”,则跳转到首页HomePage;
html
<div id="box">
<p>
<router-link to="/home">home</router-link>
<router-link to="/news">news</router-link>
<router-link to="/music">music</router-link>
<router-link to="/login">login</router-link>
</p>
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
const Home = {
template: '<div>首页</div>'
}
const News = {
template: '<div>新闻</div>'
}
const Music = {
template: '<div>音乐</div>'
}
const Login = {
template: '<div>登录</div>'
}
const routes = [{
path: '/',
component: Home
}, {
path: '/home',
component: Home
}, {
path: '/news',
component: News
}, {
path: '/music',
component: Music
}, {
path: '/login',
component: Login
}]
const router = new VueRouter({
routes // (缩写)相当于 routes: routes
})
var vm = new Vue({
el: '#box',
data: {},
router
})
// 添加全局路由守卫
router.beforeEach((to, from, next) => {
//创建守卫规则集合(这里表示'/news'与'/music'路径是需要权限验证的)
const nextRoute = ['/news', '/music'];
// 使用isLogin来模拟是否登录
let isLogin = false;
// 判断to.path(要跳转的路径)是否是需要权限验证的
if (nextRoute.indexOf(to.path) >= 0) {
if (!isLogin) {
router.push({
path: '/login'
})
location.reload(); //必须要有
}
}
// 已登录状态;当路由到login时,跳转至home
if (to.path === '/login') {
if (isLogin) {
router.push({
path: '/home'
});
location.reload();
}
}
next(); //必须要有
});
</script>
