【Vue2+Element ui通用后台】登录和退出

我们要做的权限分为两个部分:
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>

【Vue2+Element ui通用后台】登录和退出_第1张图片
接下来我们增加登录这部分的权限,我们在登录后需要生成一个 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>

保存后我们可以在浏览器控制台的应用中查看
【Vue2+Element ui通用后台】登录和退出_第2张图片
我们打开 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 删了,再刷新首页,会自动跳到登录页
【Vue2+Element ui通用后台】登录和退出_第3张图片
我们在 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)
}

当登录失败时,返回数据:
【Vue2+Element ui通用后台】登录和退出_第4张图片
当登录成功时,返回数据:
【Vue2+Element ui通用后台】登录和退出_第5张图片
当登录成功时,我们替换之前的代码存入 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')
      }
    }

【Vue2+Element ui通用后台】登录和退出_第6张图片

你可能感兴趣的:(Vue学习笔记,javascript,ui,vue.js)