路由跳转的四种方式:
1、router-link (带参数、不带参数);
2、this.$router.push() (函数里面调用,1.2.3);
3、this.$router.replce() (用法同上,push);
4、this.$router.go(n);
不带参数跳转:
<router-link :to="{path:'/permission'}">权限管理</router-link>
<router-link :to="{name:'permissionManage'}">权限管理</router-link>
// 注意:router-link中链接如果是'/' 开始就是从根部路由开始,如果开始不带'/',则从当前路由开始。
带参数跳转:
<router-link to="/menu/21/menu">菜单管理</router-link>
<router-link :to="{name:'menuManageParams', params:{id:22,name:'menu'}}">菜单管理</router-link>
// params传参数 (类似post)
// 路由配置:path:"/menu/:id" 或者 path:"/menu:id"
// 不配置path,第一次可请求,刷新页面id会消失;配置path,刷新页面id会保留
// html取参:$route.params.id
// script取参:this.$route.params.id
<router-link to="/role?id=10&name=role">角色管理</router-link>
<router-link :to="{name:'roleManage',query: {id:12,name:'role'}}">角色管理</router-link>
// query传参数(类似get,url后面会显示参数)
// html 取参 $route.query.id
// script 取参 this.$route.query.id
this.$router.push():
1、this.$router.push('/home')
2、this.$router.push('{name:‘home}')
3、this.$router.push({path:'/home'})
this.$router.go(n)
向前或者向后跳转n个页面,n可为正整数或负整数。
路由守卫及路由钩子路由守卫
路由守卫,路由跳转过程中的一些钩子函数 ,在路由跳转时,做一些判断或其它的操作, 类似于组件生命周期钩子函数 。
路由钩子
主要实现方式有三种:全局实现、路由独享和组件内实现。
全局实现
使用router.beforeEach注册一个全局的before钩子。
每个钩子方法接收三个参数:
to: Route : 即将要进入的目标 [路由对象]
from: Route : 当前导航正要离开的路由
next: Function : 继续执行函数
next():继续执行
next(false):中断当前的导航。
next('/') 或 next({ path: '/' }):跳转新页面,常用于登陆失效跳转登陆。
路由独享
在路由配置中单独加入钩子,配置路由的时候可以直接增加beforeEnter,功能类似before。
组件内实现钩子
beforeRouteEnter:进入页面前调用,在导航确认之前调用,新组件的beforeCreate之前调用,所以特别注意它的this是 undefined。
beforeRouteUpdate (2.2 新增):页面路由改变时调用,一般需要带参数,点击更新二级导航时调用。
beforeRouteLeave:离开页面调用,离开当前界面之前调用,用法:1. 需要的保存或者删除的数据没有完成当前操作等等原因,禁止界面跳转。
项目代码案例创建工程
创建项目:
> vue create demo01
> cd demo01
> npm run serve
安装依赖:
> npm install vue-router@3.5.2 --save
> npm install vuex@3.4.0 --save
> npm install element-ui@2.15.6 --save
运行效果
工程结构
项目源码:main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router/index';
import Element from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.config.productionTip = false;
//安装Element
Vue.use(Element);
new Vue({
render: h => h(App),
router: router,
}).$mount('#app')
项目源码:App.vue
<template>
<div id="app">
<Main></Main>
</div>
</template>
<script>
import Main from './views/main/Main.vue'
export default {
name: 'App',
components:{
Main
}
}
</script>
<style>
body{
margin:0;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
路由源码:router/index.js
import VueRouter from "vue-router";
import Vue from "vue"
import permissionManage from './../views/permission/permissionManage.vue'
import menuManage from './../views/menu/menuManage.vue'
import roleManage from './../views/role/roleManage.vue'
// 通过Vue.use(插件),安装插件
Vue.use(VueRouter);
// 创建VueRouter对象
const routes=[
{
path: '/'
},
{
path:'/permission',
name: 'permissionManage',
component: permissionManage
},
{
path:'/menu',
name: 'menuManage',
component: menuManage
},
{
path:'/menu/:id/:name',
name: 'menuManageParams',
component: menuManage
},
{
path:'/role',
name: 'roleManage',
component: roleManage,
meta: {
requireAuth:true
},
// 路由内钩子
beforeEnter: (to, from, next) => {
console.log('进入前执行,beforeEnter',to, from, next);
next();
}
},
{
path:'/user',
name: 'userManage',
component:() => import('./../views/user/userManage.vue')
}
];
const router = new VueRouter({
routes:routes
});
// 全局路由拦截-进入页面前执行
router.beforeEach((to, from, next) => {
console.log("beforeEach",to, from,next);
// 继续执行
next();
});
// 全局后置钩子
router.afterEach((to, from) => {
//不接受next
console.log("afterEach",to, from);
});
// 导出
export default router;
views/main/Main.vue
<template>
<div class="main">
<div class="left">
<h2 style="margin:0;padding-top:10px;height:40px;color:#f3f3f3;">测试系统</h2>
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>系统管理</span>
</template>
<el-menu-item index="1-1" @click="toMenu('/permission')">权限管理</el-menu-item>
<el-menu-item index="1-2" @click="toMenu('/menu')">菜单管理</el-menu-item>
<el-menu-item index="1-3" @click="toMenu('/role')">角色管理</el-menu-item>
<el-menu-item index="1-4" @click="toMenu('/user')">用户管理</el-menu-item>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</div>
<div class="right">
<div class="top">
</div>
<div class="center">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
export default {
name:'main',
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
},
toMenu(path){
console.log(path);
this.$router.push(path);
// this.$router.push({path:path});
}
}
}
</script>
<style>
.main{
display:flex;
height:100%;
width:100%;
}
.left {
height:100%;
width: 300px;
background-color: #0061c5;
}
.right {
height:100%;
flex: 1;
}
.top {
height:50px;
width: 100%;
background-color: #0061c5;
}
.center{
padding: 10px;
text-align:left;
}
</style>
views/permission/permissionManage.vue
<template>
<div>
<el-row style="margin-top:2px;">
<el-col :span="24">
<el-form :inline="true" :model="form">
<el-form-item label="搜索用户">
<el-input v-model="form.username" placeholder="" size="small" ></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="活动区域" size="small">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button size="small" type="primary" icon="el-icon-search" @click="onSubmit">查询</el-button>
<el-button size="small" type="primary" icon="el-icon-delete" @click="onClear">清除</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row style="margin-top:1px;">
<el-col :span="24">
<el-form :inline="true">
<el-button type="primary" plain size="mini" @click="toggleSelection([tableData[1], tableData[2]])">切换第二、第三行的选中状态</el-button>
<el-button type="success" plain size="mini" @click="toggleSelection()">取消选择</el-button>
</el-form>
</el-col>
</el-row>
<el-row style="margin-top:10px;">
<el-col :span="24">
<el-table
ref="dataTable"
:data="tableData"
border
highlight-current-row
style="width: 100%"
@current-change="handleCurrentChange"
:row-class-name="tableRowClassName">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
type="index"
fixed
label="序号"
width="50">
</el-table-column>
<el-table-column
prop="date"
fixed
label="日期"
width="180">
</el-table-column>
<el-table-column
prop="name"
fixed
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
<el-table-column
fixed="right"
label="操作"
width="200">
<template slot-scope="scope">
<el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
<el-button type="text" size="small">编辑</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
style="text-align:right;margin-right:80px;margin-top:5px;"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage4"
:page-sizes="[100, 200, 300, 400]"
:page-size="100"
layout="total, sizes, prev, pager, next, jumper"
:total="400">
</el-pagination>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name:'permission',
data() {
return {
form:{
},
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄',
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}],
currentPage1: 5,
currentPage2: 5,
currentPage3: 5,
currentPage4: 4
}
},
methods: {
tableRowClassName({row, rowIndex}) {
if (rowIndex === 1) {
return 'warning-row';
} else if (rowIndex === 3) {
return 'success-row';
}
return '';
},
handleClick(row) {
console.log(row);
},
handleCurrentChange(val) {
this.currentRow = val;
},
toggleSelection(rows) {
if (rows) {
rows.forEach(row => {
this.$refs.dataTable.toggleRowSelection(row);
});
} else {
this.$refs.dataTable.clearSelection();
}
},
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
}
}
}
</script>
<style scoped>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
views/menu/menuManage.vue
<template>
<div>
<el-row style="margin-top:2px;">
<el-col :span="24">
<h2>菜单管理</h2>
<el-button size="small" type="primary" @click="goBack()">返回</el-button>
</el-col>
</el-row>
<el-row style="margin-top:2px;">
<el-col :span="24">
<h5>页面接收:$route.params.id</h5>
{{$route.params.id}}
<h5>页面接收:$route.params.name</h5>
{{$route.params.name}}
</el-col>
</el-row>
<el-row style="margin-top:2px;">
<el-col :span="24">
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name:'menu',
data(){
return {
}
},
methods:{
goBack(){
// 向前后者向后跳转n个面,n可为正整数
this.$router.go(-1);
}
}
}
</script>
<style scoped>
</style>
views/role/roleManage.vue
<template>
<div>
<el-row style="margin-top:2px;">
<el-col :span="24">
<h2>角色管理</h2>
<el-button size="small" type="primary" @click="goBack()">返回</el-button>
</el-col>
</el-row>
<el-row style="margin-top:2px;">
<el-col :span="24">
<h5>页面接收:$route.query.id</h5>
{{$route.query.id}}
<h5>页面接收:$route.query.name</h5>
{{$route.query.name}}
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name:'role',
methods:{
goBack(){
// 向前后者向后跳转n个面,n可为正整数
this.$router.go(-1);
}
},
// 进入页面前调用
beforeRouteEnter(to, from, next) {
console.log('进入enter路由钩子')
next()
},
// 离开页面调用
beforeRouteLeave(to,from, next){
console.log('进入leave路由钩子')
next()
},
// 页面路由改变时调用
beforeRouteUpdate(to, from, next) {
console.log('进入update路由钩子')
console.log(to.params.id)
next()
},
}
</script>
<style scoped>
</style>
views/user/userManage.vue
<template>
<div>
<el-row style="margin-top:2px;">
<el-col :span="24">
<h2>用户管理</h2>
<el-button size="small" type="primary" @click="goBack()">返回</el-button>
</el-col>
</el-row>
<el-row style="margin-top:2px;">
<el-col :span="24">
<h5>router-link(不带参数)</h5>
<router-link :to="{path:'/permission'}">权限管理</router-link> |
<router-link :to="{name:'permissionManage'}">权限管理</router-link>
<br/>
<el-link type="primary" @click="toPermission1()">权限管理</el-link> |
<el-link type="primary" @click="toPermission2">权限管理</el-link>
</el-col>
</el-row>
<el-row style="margin-top:2px;">
<el-col :span="24">
<h5>router-link(带参数)</h5>
<router-link to="/role?id=10&name=role">角色管理</router-link> |
<router-link :to="{name:'roleManage',query: {id:12,name:'role'}}">角色管理</router-link>
<br/>
<el-link type="primary" @click="toRole1()">角色管理</el-link> |
<el-link type="primary" @click="toRole2">角色管理</el-link>
<br/>
<router-link to="/menu/21/menu">菜单管理</router-link> |
<router-link :to="{name:'menuManageParams', params:{id:22,name:'menu'}}">菜单管理</router-link>
<br/>
<el-link type="primary" @click="toMenu1()">角色管理</el-link> |
<el-link type="primary" @click="toMenu2">角色管理</el-link>
<br/>
<el-link type="primary" @click="toMenu21()">角色管理</el-link> |
<el-link type="primary" @click="toMenu22">角色管理</el-link>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name:'user',
data(){
return {
}
},
methods:{
goBack(){
this.$router.go(-1);
},
// 权限管理
toPermission1(){
this.$router.push('/permission');
},
toPermission2(){
this.$router.push({name:'permissionManage'});
},
// 角色管理
toRole1(){
this.$router.push('/role?id=10&name=role');
},
toRole2(){
this.$router.push({name:'roleManage',query: {id:12,name:'role'}});
},
// 菜单管理
toMenu1(){
this.$router.push('/menu/21/menu');
},
toMenu2(){
this.$router.push({name:'menuManageParams', params:{id:22,name:'menu'}});
},
toMenu21(){
this.$router.replace('/menu/21/menu');
},
toMenu22(){
this.$router.replace({name:'menuManageParams', params:{id:22,name:'menu'}});
},
}
}
</script>
<style scoped>
</style>