我们要做的权限分为两个部分:
1、在未登录前,浏览器中输入其他页面网址不能打开
2、登录后,不同账号展示的菜单不同
首先我们增加登录页,在 views 中增加 Login.vue
然后修改 idnex.js
......
//1、创建组件
......
import Login from '../views/Login';
Vue.use(VueRouter)
//2、将路由与组件进行映射
const routes = [
{
......
},
{
path: '/login',
name: 'name',
component: Login
}
]
......
登录页用到了 Form表单
<template>
<el-form :label-width='70' class="login-container" ref="form" :model="form" :rules="rules" label-width="80px">
<h3 class="login_title">系统登录</h3>
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="form.password" autocomplete="off" placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" style="margin-left: 105px;margin-top: 10px">登录</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
data(){
return{
form:{
username:'',
password:''
},
rules:{
username:[ { required: true, message: '请输入用户名', trigger: 'blur' } ],
password:[ { required: true, message: '请输入密码', trigger: 'blur' }]
}
}
}
}
</script>
<style lang="less" scoped>
.login-container{
width: 350px;
border: 1px solid #eaeaea;
margin: 180px auto;
padding: 35px 35px 15px 35px;
background-color: #ffffff;
border-radius: 15px;
box-shadow: 0 0 25px #cac6c6;
box-sizing: border-box;
.login_title{
text-align: center;
margin-bottom: 40px;
color: #505458;
}
.el-input{
width: 198px;
}
}
</style>
接下来我们增加登录这部分的权限,我们在登录后需要生成一个 token 来进行身份验证
首先,生成的 token 数据用 cookie 保存,所以我们还需要下载插件,执行npm i [email protected]
我们修改 Login.vue 给登录增加 click 事件
<template>
......
<el-form-item>
<el-button type="primary" @click="submit" style="margin-left: 105px;margin-top: 10px">登录</el-button>
</el-form-item>
......
</template>
<script>
import Mock from 'mockjs'
import Cookie from 'js-cookie'
export default {
data(){
......
},
methods:{
// 登录
submit(){
// token信息,我们通过mock模拟,生成一个随机数
const token = Mock.Random.guid();
// token信息存入cookie用于不同页面间的通讯
Cookie.set('token',token);
// 跳转首页
this.$router.push('/home')
}
}
}
</script>
保存后我们可以在浏览器控制台的应用中查看
我们打开 vue router,切换到 3.x 版本,打开导航守卫-全局前置守卫,可以参考这里我们修改 main.js
......
import Cookie from 'js-cookie'
......
Vue.use(ElementUI);
// 添加全局前置路由守卫
router.beforeEach((to, from, next) => {
// 判断token是否存在
const token = Cookie.get('token');
// token 不存在,说明当前用户未登录,应跳转至登录
if (!token && to.name !== 'login') {
next({name: 'login'})
} else if (token && to.name === 'login') {// 如果token存在,说明登录成功,跳转首页
next({name: 'home'})
} else {
next()
}
})
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
登录后跳转首页,这时候已经保存了 token。所以当再改为 login 路径进入登录页时是不可以的
当我们把 token 删了,再刷新首页,会自动跳到登录页
我们在 mockServeData 中新建 permission.js
import Mock from 'mockjs'
export default {
getMenu: config => {
const {username, password} = JSON.parse(config.body)
// 先判断用户是否存在
// 判断账号和密码是否对应
if (username === 'admin' && password === 'admin') {
return {
code: 20000,
data: {
menu: [
{
path: '/home',
name: 'home',
label: '首页',
icon: 's-home',
url: 'Home.vue'
},
{
path: '/mall',
name: 'mall',
label: '商品管理',
icon: 'video-play',
url: 'Mall.vue'
},
{
path: '/user',
name: 'user',
label: '用户管理',
icon: 'user',
url: 'User.vue'
},
{
label: '其他',
icon: 'location',
children: [
{
path: '/page1',
name: 'page1',
label: '页面1',
icon: 'setting',
url: 'PageOne.vue'
},
{
path: '/page2',
name: 'page2',
label: '页面2',
icon: 'setting',
url: 'PageTwo.vue'
}
]
}
],
token: Mock.Random.guid(),
message: '获取成功'
}
}
} else if (username === 'xiaoxiao' && password === 'xiaoxiao') {
return {
code: 20000,
data: {
menu: [
{
path: '/home',
name: 'home',
label: '首页',
icon: 's-home',
url: 'Home.vue'
},
{
path: '/video',
name: 'video',
label: '商品管理',
icon: 'video-play',
url: 'Mall.vue'
}
],
token: Mock.Random.guid(),
message: '获取成功'
}
}
} else {
return {
code: -999,
data: {
message: '密码错误'
}
}
}
}
}
修改 mock.js
......
import permission from './mockServeData/permission'
......
Mock.mock(/api\/permission\/getMenu/,'post',permission.getMenu);
在 index.js 中增加
export const getMenu = (data)=>{
return http.post('/permission/getMenu',data)
}
当登录失败时,返回数据:
当登录成功时,返回数据:
当登录成功时,我们替换之前的代码存入 token。当登录失败时,我们用 Message进行一个友好的提示
import Cookie from "js-cookie";
submit(){
//校验通过
this.$refs.form.validate((valid)=>{
if(valid){
getMenu(this.form).then(({data})=>{
// console.log('TTT',data);
if(data.code === 20000){
// token信息存入cookie用于不同页面间的通讯
Cookie.set('token',data.data.token);
// 跳转首页
this.$router.push('home')
} else {
this.$message.error('账号信息错误');
}
})
}
})
}
修改 CommonHeader.vue,给退出增加退出的相关事件,给 dropdown 增加点击事件不是直接增加 @click
,可以参考 dropdown
<el-dropdown @command="handleCommand">
<span class="el-dropdown-link">
<img class="user" src="../assets/logo.png"/>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人中心</el-dropdown-item>
<el-dropdown-item command="cancel">退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
handleCommand(command){
if(command === 'cancel'){
// 清除Cookie中的token数据
Cookie.remove('token');
// 登出后跳转登录页
this.$router.push('login')
}
}