【Vue.js+Element UI+ Node.js】实现完整登录验证

【Vue.js+Element UI+ Node.js】实现登录验证

在这里插入图片描述

1.配置主页和登录页的路由router

/src/main.js

import Vue from 'vue'
// 引入Element UI组件
import ElementUI from 'element-ui'
// 引入Element UI样式文件
import 'element-ui/lib/theme-chalk/index.css'
import App from './App'
import router from './router'
// 引入reset.css
import './assets/css/reset.css'

// 使用Element UI(注册组件)
Vue.use(ElementUI)
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

/src/router/route.js

const routes = [
  {
    path: '/',
    name: 'Index',
    component: () => import('@/pages/main/Index')
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('@/pages/login/Index'),
    meta: {
      title: 'Login'
    }
  }
]

export default routes

2.路由拦截
  • 设置页面标题
  • 如果要跳转的页面不是登录页面,就必要登录成功之后才能访问
  • 跳转的就是登录页面,不做拦截
    /src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
// 导入路由规则
import routes from './routes'

Vue.use(Router)

const router = new Router({
  mode: 'history',
  routes
})

// 拦截
router.beforeEach((to, from, next) => {
  // console.log(to.meta)
  // 设置页面标题
  document.title = to.meta.title || 'United Mall Backend Management System'
  // 如果要跳转的页面不是登录页面,就必须要登录成功之后才能访问
  if (to.path === '/login') {
    // 跳转的就是登录页面,不做拦截
    next()
  } else {
    // 跳转的不是登录页面,需要登录以后才能够访问到
    const userInfo = sessionStorage.getItem('user')
    if (!userInfo) {
      // 没有登录,则跳转登录页面
      next('/login')
    } else {
      next()
    }
  }
})

export default router

3.利用Element-UI组件完成登录页的样式设置和表单验证

/src/pages/login/Index.vue

<template>
  <div class = "main">
    <div class="loginform">
        <h3 class="title">管理员登录</h3>
        <el-form ref="form" :model="loginInfo" :rules = "rules">
          <el-form-item label="" prop = "username">
            <el-input v-model="loginInfo.username" placeholder="请输入账号" clearable>
                <template slot="prepend">
                  <i class="el-icon-s-custom"></i>
                </template>
            </el-input>
          </el-form-item>
          <el-form-item label="" prop = "password">
            <el-input v-model="loginInfo.password" placeholder="请输入密码" show-password clearable>
                <template slot="prepend">
                  <i class="el-icon-lock"></i>
                </template>
            </el-input>
          </el-form-item>
          <el-form-item label="">
            <el-button type="primary" @click="onSubmit" class="loginbtn">登录</el-button>
          </el-form-item>
        </el-form>
    </div>
  </div>
</template>

<script>
// 从user中导出登录方法
import { login } from '@/api/user'

export default {
  data () {
    return {
      loginInfo: {
        username: '',
        password: ''
      },
      rules: {
        // 规则的编写
        username: [
          { required: true, message: '请输入账号', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    onSubmit () {
    //   console.log('on submit')
      // 触发表单验证 调用Form组件的validate回调方法
      this.$refs.form.validate(valid => {
        // validate表示验证是否全部通过
        // console.log('valid', valid)
        if (valid) {
        // 全部通过
          this.login()
        }
      })
    },
    login () {
      // 登录处理
      login(this.loginInfo.username, this.loginInfo.password).then(res => {
        // console.log(res)
        // 登录成功, 把返回的信息保存到sessionStorage中
        sessionStorage.setItem('user', JSON.stringify(res))
        // 跳转到后台首页
        this.$router.replace('/')
      }).catch(err => {
        // console.error(err.message)
        // 登录失败,显示错误信息
        this.$message.error(err.message)
      })
    }
  }
}
</script>

<style scoped>
.main {
    width: 100%;
    height: 100%;
    background: url('~@/assets/images/loginbg.jpg') no-repeat;
    background-size: cover;
    display: flex;
    justify-content: center;
    align-items: center;
}
.loginform {
    background: #ffffff;
    padding:18px 28px;
    border-radius: 10px;
}
.loginform .title {
    font-size: 18px;
    font-weight: 700;
    text-align: center;
    margin-bottom: 20px;
}
.loginform .loginbtn {
    width:100%
}
</style>

4.解决跨域问题,配置代理

config/index.js

// 代理配置
    proxyTable: {
      "/api":{
        target:"http://localhost:3000",
        changeOrigin: true,
        pathRewrite:{
          // url路径重写
          "^/api": "/api"
        }
      }
    },
5.配置接口文件,

/src/api/http.js

import axios from 'axios'

// 1.创建一个axios实例, 不污染全局的axios对象
const http = axios.create({
  baseURL: '/api', // 会产生所有的axios的url前添加/api
  timeout: 5000 // 超时的时间
})

// 2.响应拦截
http.interceptors.response.use(function (response) {
  response = response.data
  // console.log('http interceptors', response)
  if (response.code === 200) { // 接口请求成功(包括数据正常返回)
    return response.list || null
  }
  return Promise.reject(new Error(response.msg))
}, function (error) {
  return Promise.reject(error)
})
export default http

6.封装登录方法

/src/user.js

import http from './http'

// 登录
export const login = (username, password) => {
  if (!username || !password) {
    return Promise.reject(new Error('账号或密码为空'))
  }
  return http.post('/userlogin', {
    username,
    password
  })
}

在这里插入图片描述

7.登录
  • 登录成功, 把返回的信息保存到sessionStorage中
  • 登录成功,跳转到后台首页
  • 登录失败,显示错误信息
 login () {
      // 登录处理
      login(this.loginInfo.username, this.loginInfo.password).then(res => {
        // console.log(res)
        // 登录成功, 把返回的信息保存到sessionStorage中
        sessionStorage.setItem('user', JSON.stringify(res))
        // 跳转到后台首页
        this.$router.replace('/')
      }).catch(err => {
        // console.error(err.message)
        // 登录失败,显示错误信息
        this.$message.error(err.message)
      })
    }
8.退出登录

退出登录时清除本地存储中的登录用户信息,并跳转登录页面
/components/Header.vue

<template>
  <div class="header">
    <div class="logo">United Mall后台管理系统</div>
    <!-- 下拉菜单选项
        divided 添加横线
        disabled 禁用 -->
    <el-dropdown  @command = "handleCommand">
      <span class="el-dropdown-link">
        欢迎!{{username}}<i class="el-icon-arrow-down el-icon--right"></i>
      </span>
      <el-dropdown-menu slot="dropdown">
        <el-dropdown-item command = "personInfo">个人信息</el-dropdown-item>
        <el-dropdown-item command = "changePwd">修改密码</el-dropdown-item>
        <el-dropdown-item divided command = "logout">退出系统</el-dropdown-item>
      </el-dropdown-menu>
    </el-dropdown>
  </div>
</template>

<script>
export default {
  data () {
    return {
      username: ''
    }
  },
  mounted () {
    // 从本地存储中获取登录用户的信息
    const userInfo = JSON.parse(sessionStorage.getItem('user'))
    this.username = userInfo.username // 获取登录用户的账号
    // console.log(userInfo)
  },
  methods: {
    handleCommand (command) {
      // console.log('command', command)
      // 必须保证command和对应的方法名称相同
      this[command]()
    },
    personInfo () {
      console.log('personal info')
    },
    changePwd () {
      console.log('change password')
    },
    logout () {
      console.log('log out')
      // 退出系统
      // 清除本地存储中的登录用户信息
      sessionStorage.removeItem('user')
      // 跳转登录页面
      this.$router.replace('/login')
    }
  }
}
</script>

<style scoped>
.header {
  width: 100%;
  height: 100%;
  background: #518ecb;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  box-sizing: border-box;
}
.logo {
  font-size: 20px;
  font-weight: 700;
  color: #ffffff;
}
.el-dropdown-link {
 color: #ffffff;
}
</style>

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值