电商后台管理系统登录功能前端实现
2022-08-03 09:57:03
153
{{single.collect_count}}

目录

一 登录概述

1 登录业务流程

2 登录业务的相关技术点

3 token 和 cookie/session 一般选型策略

4 路由导航守卫控制访问权限

5 退出功能实现原理

二 登录—— token 原理分析

三 登录功能实现

登录页面的布局

四 梳理项目结构

1 清理 APP.vue组件

2 清理路由文件 index.js

3 删除不必要的文件

五 安装less-Loader和less依赖

六 将阿里的图标库放到下面目录

七 代码

1 新建登录组件 Login.vue

2 修改路由 index.js

3 修改APP.vue,添加路由占位符

4 新建全局样式 global.css

5 修改入口文件main.js

6 因为是按需导入的,修改element.js

7 创建一个简单的Home.vue进行测试

八 测试

1 登录前页面

2 输入正确的用户名和密码,成功登录

3 点击退出按钮后的页面

九 源码


一 登录概述

1 登录业务流程

a 在登录页面输入用户名和密码

b 调用后台接口进行验证

c 通过验证之后,根据后台的响应状态跳转到项目主页

2 登录业务的相关技术点

  • http 是无状态的

  • 通过 cookie 在客户端记录状态

  • 通过 session 在服务端记录状态

  • 通过 token 方式维持状态

3 token 和 cookie/session 一般选型策略

当前端和后端项目存在跨域,推荐使用token方式。

当前端和后端项目不存在跨域,推荐使用cookie和session技术。vue前后端使用的是跨域,一般使用token。

4 路由导航守卫控制访问权限

如果用户没有登录,但是直接访问URL访问特定的页面,需要重新导航到登录页面。

5 退出功能实现原理

基于 token 方式实现退出比较简单,只需要销毁本地的 token 即可,后续请求就不会携带 token,必须重写登录生成一个新的 token 之后才可以访问页面。

二 登录—— token 原理分析

三 登录功能实现

登录页面的布局

通过 Element-UI 组件实现布局,会用到下面组件:

  • el-form
  • el-form-item
  • el-input
  • el-button
  • 字体图标

这些组件布局后的效果如下:

四 梳理项目结构

1 清理 APP.vue组件

<template><div id="app"></div></template><script>export default {name: 'app'}</script><style></style>

2 清理路由文件 index.js

import Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter)const routes = []const router = new VueRouter({routes})export default router

3 删除不必要的文件

  • About.vue
  • Home.vue
  • HelloWorld.vue

五 安装less-Loader和less依赖

六 将阿里的图标库放到下面目录

F:\vue\vue_shop\src\assets

文件从: https://gitee.com/cakin24/vue-shop-admin/tree/master/src/assets 获取

七 代码

1 新建登录组件 Login.vue

<!--结构--><template><div class="login_container"><!-- 登录盒子 --><div class="login_box"><!-- 头像区域 --><div class="avatar_box"><img src="../assets/logo.png" alt=""></div><!-- 登录表单区 --><!-- 用 ref 表示表单的实例对象 用 :model 进行表单属性绑定,用 :rules 绑定表单验证规则 --><el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form"><!--用户名--><!--prop指定校验规则--><el-form-item prop="username"><!-- 使用的是阿里的图标库 用 v-model 进行数据双向绑定--><el-input prefix-icon="iconfont icon-user" v-model="loginForm.username"></el-input></el-form-item><!--密码--><el-form-item prop="password"><!-- 使用的是阿里的图标库,密码框用show-password --><el-input prefix-icon="iconfont icon-3702mima" v-model="loginForm.password"show-password></el-input></el-form-item><!--按钮--><el-form-item class="btns"><el-button type="primary" @click="login">登录</el-button><el-button type="info" @click="resetLoginForm">重置</el-button></el-form-item></el-form></div></div></template><!--行为--><script>export default {name: "Login",data() {return {// 这是登录表单的数据表单对象loginForm: {username: 'admin',password: '123456'},// 这是表单的验证规则对象loginFormRules: {// 验证用户名是否合法username: [{required: true, message: '请输入登录名称', trigger: 'blur'},{min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur'}],// 验证密码是否合法password: [{required: true, message: '请输入登录密码', trigger: 'blur'},{min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur'}]}}},methods: {// 点击重置按钮,重置登录表单:resetFieldsresetLoginForm() {this.$refs.loginFormRef.resetFields();},// 登录预验证:validatelogin() {this.$refs.loginFormRef.validate(async (valid) => {if (!valid) return;// data 重命名为resconst {data: res} = await this.$http.post('login', this.loginForm);if (res.meta.status !== 200) return this.$message.error("登录失败!")this.$message.success("登录成功!")/** 1 将登录成功之后的 token,保存到客户端的 sessionStorage 中*1.1 项目中除了登录之外的其他API接口,必须在登录之后才能访问*1.2 token 只应在当前网站打开期间生效,所以将 token 保存在 sessionStorage 中* 2 通过编程式导航跳转到后台主页,路由地址是 /home* */// 将 token 保存到 浏览器的 [Application] -> [sessionStorage] 中window.sessionStorage.setItem('token', res.data.token)this.$router.push('/home')})}}}</script><!--样式--><!-- scoped:只在当前组件中生效 --><style lang="less" scoped>.login_container {background-color: #2b4b6b;/* 使得 login_container 占满全屏 */height: 100%;}.login_box {width: 450px;height: 300px;background-color: #fff;/* 圆角边框 */border-radius: 3px;/* 盒子定位,使得盒子位于屏幕的正中间 */position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);/* 盒子嵌套,修饰图片 */.avatar_box {height: 130px;width: 130px;border: 1px solid #eee;border-radius: 50%;padding: 10px;/* 加阴影 */box-shadow: 0 0 10px #ddd;/* 定位盒子 */position: absolute;left: 50%;transform: translate(-50%, -50%);background-color: #fff;img {width: 100%;height: 100%;/* 圆角边框 */border-radius: 50%;background-color: #eee;}}}.login_form {position: absolute;bottom: 0;width: 100%;padding: 0 20px;box-sizing: border-box;}/* 跳转button的位置 */.btns {display: flex;justify-content: flex-end;}</style>

2 修改路由 index.js

import Vue from 'vue'import VueRouter from 'vue-router'// 导入登录组件import Login from "../components/Login";import Home from "../components/Home";import {renderThumbStyle} from "element-ui/packages/scrollbar/src/util";Vue.use(VueRouter)const routes = [// 路由重定向,当访问/,就会重定向到/login{path: '/',redirect: '/login'},// 定义登录路由规则{path: '/login',component: Login},// 定义Home的路由规则{path: '/home',component: Home}]const router = new VueRouter({routes})// 挂载路由导航守卫// to 将要访问的路径// from 代表从哪个路径跳转而来// next 是个函数,表示放行 next() 放行next('/login') 强制跳转router.beforeEach((to, from, next) => {// 如果用户访问的登录页,直接放行if (to.path === '/login') return next();// 从 sessionStorage 中获取到保存的 token 值const tokenstr = window.sessionStorage.getItem('token')// 没有 token,强制跳转到登录页if (!tokenstr) return next('/login')next()})export default router

3 修改APP.vue,添加路由占位符

<template><div id="app"><!-- 路由占位符--><router-view></router-view></div></template><script>export default {name: 'app'}</script><style></style>

4 新建全局样式 global.css

/* 全局样式 *//* 撑满全屏 */html, body, #app {height: 100%;margin: 0;padding: 0;}

5 修改入口文件main.js

import Vue from 'vue'import App from './App.vue'import router from './router'import './plugins/element.js'// 导入阿里的字体图标import './assets/fonts/iconfont.css'// 导入全局样式表,使得全局样式生效import './assets/css/global.css'// 全局导入axiosimport axios from 'axios'// 设置axios请求的根路径axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'Vue.prototype.$http = axiosVue.config.productionTip = falsenew Vue({router,render: h => h(App)}).$mount('#app')

6 因为是按需导入的,修改element.js

import Vue from 'vue'import { Button } from 'element-ui'import { Form ,FormItem} from 'element-ui'import { Input } from 'element-ui'// 导入弹框提示组件import { Message } from 'element-ui'Vue.use(Button)Vue.use(Form)Vue.use(FormItem)Vue.use(Input)// 这里和其他组件不一样,需要通过 prototype 全局挂载 MessageVue.prototype.$message = Message

7 创建一个简单的Home.vue进行测试

<template><div><el-button type="info" @click="logout">退出</el-button></div></template><script>export default {name: "Home",methods:{logout(){window.sessionStorage.clear()this.$router.push("/login")}}}</script><style scoped></style>

八 测试

1 登录前页面

2 输入正确的用户名和密码,成功登录

3 点击退出按钮后的页面

九 源码

https://gitee.com/cakin24/vue_shop

回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}