3.登录/退出功能

3.1登录概述

3.1-1.登录业务流程

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

②调用后台接口进行验证

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

3.1-2.登录业务的相关技术点

  • http 是无状态的(需要记录用户的登录状态)

    • 通过 cookie 在客户端记录状态
    • 通过 session 在服务器端记录状态
    • 通过 token 方式维持状态

3.2登录–token原理分析

1.如果前端和后台接口之间不存在跨域问题,推荐使用Cookie或者session记录登录状态。
2.如果前端和后台接口存在跨域问题,则使用token。
分析:token原理现在有客户端和服务器服务器:专门提供API接口。如登录接口客户端:需要通过ajax请求,访问服务器上的数据目前:客户端与服务器之间存在跨域问题
token原理:
1.客户端在登录页面输入用户名和密码,把这次请求提交到服务器。
2.服务器根据用户的这次请求验证用户是否存在。如果登录成功之后,服务器向客户端返回一个唯一的token值。
3.客户端需要把服务器返回的token值,记录到客户端本地。
4.今后如果客户端要请求服务器的API接口,必须携带token才能够正常的进行操作。如果客户端在发起下一次请求的时候,携带了token。
5.服务器接收到token之后,验证token是否存在:如果存在证明用户已登录然后会根据携带的token验证是哪个用户,从而根据用户的操作返回不同的结果。注意事项:
1.token值是由服务器生成,而且每个不同的用户生成的token值也是不一样的。
2.token值记录了用户的登录状态
3.token:客户端与服务器端进行身份校验

3.3登录功能实现

1.登录页面的布局

通过Element–UI组件实现布局

  • el-form
  • el-form-item
  • el-input
  • el-button
  • 字体图标
找到自己的项目 vue_shop
打开vscode,在项目根目录vue_shop运行:git status

注意:在开发中只有开发新功能了,尽量把功能放在新的分支上进行开发;分支开发完成以后再把这个分支合并到master分支上

​ 1.创建分支命令:git checkout -b 分支名

​ 2.在项目根目录,运行:git checkout -b login

​ 3.查看所有分支,运行:git branch 分支前存在* 表示当前处于这个分支 *login

梳理vue项目的结构,删除不必要的内容

  • 1.App.vue根组件
<template><div id="app">APP根组件</div>
</template><script>
export default {name: 'app'
}
</script><style>
</style>
  • 2.路由 router.js
import Vue from 'vue'              指的是引入vue.js文件
import Router from 'vue-router'
Vue.use(Router)                    Vue.use() 明确地安装路由功能export default new Router({routes: []
})
  • 3.删除views文件夹
  • 4.删除components/HelloWorld.vue文件

功能:创建登录组件,通过路由的形式渲染到App根组件,添加路由重定向redirect

  • 1.在components/新建登录组件:Login.vue
<template><div>登录组件</div>
</template><script>
export default {}
</script><style lang="less" scoped></style>注意:
1.lang="less"  支持less语法格式
2.scoped是vue的指令。控制组件样式生效的区间如果加上scoped,样式只在当前组件内生效如果去掉scoped,样式会全局生效一个组件它的样式是来美化自己组件结构的,不应该影响其他的组件
所以:只要定义的是单文件组件,一定为style标签加上scoped指令避免组件之间的样式冲突
  • 2.在路由 router.js 导入路由–添加路由规则
import Vue from 'vue'
import Router from 'vue-router'
import Login from '../components/Login.vue'Vue.use(Router)export default new Router({routes: [{path: '/',redirect: '/login'}, {path: '/login',component: Login}]
})
  • 3.在根组件 App.vue,添加路由占位符
<template><div id="app"><!-- 路由占位符 --><router-view></router-view></div>
</template>

功能:完成登录组件的基本页面布局:全屏背景色–登录的盒子

实现全屏背景色

  • 1.在src/assets/新建css文件夹/新建global.css
html,
body,
#app {height: 100%;margin: 0;padding: 0;
}
  • 2.在入口文件main.js中导入全局样式表:import ‘./assets/css/global.css’
  • 3.在Login.vue中,为style标签添加 height: 100%;
<style lang="less" scoped>.login_container{height: 100%;background-color: #2b4b6b;}
</style>

登录的盒子 login_box

在Login.vue文件中:

<template><div class="login_container"><div class="login_box"></div></div>
</template><script>
export default {}
</script><style lang="less" scoped>.login_container{height: 100%;background-color: #2b4b6b;}.login_box{width: 450px;height: 300px;background-color: #fff;border-radius: 3px;position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%)}
</style>

功能:绘制图像区域 avatar_box

<template><div class="login_container"><div class="login_box"><div class="avatar_box"><img src="../assets/logo.png" alt=""></div></div></div>
</template><script>
export default {}
</script><style lang="less" scoped>.login_container{height: 100%;background-color: #2b4b6b;}.login_box{width: 450px;height: 300px;background-color: #fff;border-radius: 3px;position: absolute;top: 50%;left: 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;}}}
</style>

功能:登录的表单区域

打开Element-UI官网,粘贴对应的html结构

因为我们的组件是按需导入的,所以如果用到form表单、input输入框等

  • 1.需要先在src/plugins/element.js,引入相关的组件
// 按需导入
import { Button } from 'element-ui'
import { Form, FormItem } from 'element-ui'
import { Input } from 'element-ui'// 注册全局组件
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItemon)
Vue.use(Input)
  • 2.在Login.vue文件中: Form表单–Button按钮–Input输入框
<template><div class="login_container"><div class="login_box"><!-- 头像区域 --><div class="avatar_box"><img src="../assets/logo.png" alt=""></div><!--登录表单区域 --><el-form class="login_form"><!-- 用户名区域 --><el-form-item><el-input></el-input></el-form-item><!-- 密码区域 --><el-form-item><el-input></el-input></el-form-item><!-- 按钮区域 --><el-form-item class="btns"><el-button type="primary">登录</el-button><el-button type="info">重置</el-button></el-form-item></el-form></div></div>
</template><script>
export default {}
</script><style lang="less" scoped>.login_container{height: 100%;background-color: #2b4b6b;}.login_box{width: 450px;height: 300px;background-color: #fff;border-radius: 3px;position: absolute;top: 50%;left: 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;}.btns{display: flex;justify-content: flex-end;}
</style>

功能:绘制密码和小图标

  • 1.在Element-UI官网查找:输入框–带 icon 的输入框
 <el-input  prefix-icon="el-icon-search"></el-input>    el-icon-search 需要被替换为 iconfont icon-user

因为Element-UI官网找不到需要的图标,所以借助第三方图标库。

下载好之后,将字体图标文件fonts,放在assets文件夹里面 assets/fonts

  • 2.然后在main.js导入
// 导入字体图标
import './assets/fonts/iconfont.css'
  • 3.在Login.vue中,iconfont 图标名
 <el-input prefix-icon="iconfont icon-user"></el-input>       用户头像<el-input prefix-icon="iconfont icon-3702mima"></el-input>   用户密码锁

功能:实现表单的数据绑定(element文档提供的做法)

  • 1.为el-form标签添加model 属性绑定到数据对象form :model = ‘form’
  • 2.为每一个表单项,通过v-model绑定到数据对象上的属性中
<template><div class="login_container"><div class="login_box"><!-- 头像区域 --><div class="avatar_box"><img src="../assets/logo.png" alt=""></div><!--登录表单区域 --><el-form :model="loginForm" class="login_form"><!-- 用户名区域 --><el-form-item><el-input v-model="loginForm.username" prefix-icon="iconfont icon-user"></el-input></el-form-item><!-- 密码区域 --><el-form-item><el-input v-model="loginForm.password" prefix-icon="iconfont icon-3702mima" type="password"></el-input></el-form-item><!-- 按钮区域 --><el-form-item class="btns"><el-button type="primary">登录</el-button><el-button type="info">重置</el-button></el-form-item></el-form></div></div>
</template><script>
export default {data(){return {// 这是登录表单的数据绑定对象loginForm: {username: 'wuddong',password: '123'}}}
}
</script>

功能:表单的数据验证(这是element官网文档提供的做法)

  • 为el-form标签通过绑定rules属性,指定校验对象(自定义) :rules="loginFormRules"
  • 在data数据中定义校验对象:loginFormRules,其中每一个属性就是一个验证规则(数组)
  • 为不同的表单el-form-item项,通过prop指定不同的验证规则进行表单验证

在Login.vue文件中:

第一步:<el-form :model="loginForm" :rules="loginFormRules" class="login_form"></el-form>第二步:在data数据中// 这是表单的验证规则对象(required: true  表示必填项;trigger: 'blur' 表示鼠标离开进行验证)loginFormRules:{// 验证用户名是否合法username: [{ required: true, message: '请输入用户名', trigger: 'blur' },{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }],// 验证密码是否合法password: [{ required: true, message: '请输入密码', trigger: 'blur' },{ min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }]}第三步:
用户名区域  <el-form-item prop="username"></el-form-item>
密码区域    <el-form-item prop="password"></el-form-item>

功能:表单的重置—点击重置按钮,重置表单的效验–resetFields

Vue直接操作DOM1.通过ref标注DOM元素// 在DOM元素上通过ref属性标注,属性名称自定义  <div ref="info">hello</div>2.通过$refs获取DOM元素// 通过Vue实例的$refs获取标记ref属性的元素let info = this.$refs.info.innerHTMLconsole.log(info) // hello

方法:查询官方文档form–Form Methods 拿到表单的实例对象Form,调用resetFields函数

  • 为表单el-form添加ref引用,ref引用指定的值就是表单的引用对象loginFormRef

  • 为重置按钮添加事件 @click=“resetLoginForm”,触发resetLoginForm事件处理函数

  • 在resetLoginForm事件处理函数中,通过this.$refs.loginFormRef.resetFields()

    在Login.vue文件中

第一步:登录表单区域  <el-form ref="loginFormRef"> </el-form>
第二步:<el-button type="info" @click="resetLoginForm">重置</el-button>
第三步:在script标签定义methods方法methods:{// 点击重置按钮,重置登录表单resetLoginForm(){console.log(this); //结果是组件的实例对象,里面有个属性$refsthis.$refs.loginFormRef.resetFields();}}

功能:实现登录前表单数据的预验证–validate

方法:查询官方文档form–Form Methods 拿到表单的引用对象,调用validate函数

  • 获取表单的引用对象loginFormRef

  • 拿着引用对象loginFormRef,调用validate函数进行表单预校验;

    在validate中它接收一个回调函数,第一个形参是验证的结果:布尔值

    第一步:为登录按钮添加点击事件  <el-button type="primary" @click="login">登录</el-button>
    第二步:在script标签的methods方法中login(){this.$refs.loginFormRef.validate(valid=>{console.log(valid);})
    }
    
功能:配置axios发起登录请求1.如果要请求服务器:- 启动MySql服务器(Phpstudy服务器)
- 找到素材/vue-api-server/app.js,在窗口启动:node  app.js2.在main.js中:配置axios (重点)​```js
// 导入axios包
import axios from 'axios'
// 配置请求的根路径
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
// 把axios包挂载到vue原型对象上:这样每一个vue组件都可以通过this直接访问到$http,从而去发起ajax请求
Vue.prototype.$http = axios

3.根据验证的结果valid,判断是否发起登录请求

如果请求成功,Login.vue

  • 请求方式:post
  • 请求地址:login
  • 请求参数:this.loginForm
  login(){this.$refs.loginFormRef.validate(async valid=>{console.log(valid); //valid是布尔值:true 或者 false//******************内容如下:if(!valid) return;   不发起请求const {data: res} = await this.$http.post("login",this.loginForm);console.log(res);// {data: null, meta: {…}}if(res.meta.status !== 200) return console.log('登录失败');console.log('登录成功');})}}因为post请求的结果是promise实例对象,所以在函数使用 await async
这样结果是:服务器返回的数据是一个对象:{data: {…}, status: 200, statusText: "OK", headers: {…}, config: {…}, …}**es6语法:取对象里面的属性值**我们只需要里面的data对象,所以结构复制出data属性重命名为res对象{data: res}  res就是data对应的属性值
然后根据res的meta属性,判断是否登录成功  res.meta.status !== 200

功能:配置Message全局弹框组件

需求:登录成功或者失败,给用户友好提示

配置方法:

  • 从element-ui中导入弹框组件 import { Message } from 'element-ui'
  • 把弹框组件挂载到vue的原型对象上 Vue.prototype.$message = Message
  • 调用$message提供的方法

查看官方文档:Message消息提示

plugins/element.js中,导入弹框提示组件:

// 导入弹框提示组件
import { Message } from 'element-ui'
Vue.prototype.$message = Message  注意:
1.$message是自定义属性
2.Vue.prototype.$message = Message  表示把弹框组件挂载到vue的原型对象上,这样每一个组件都可以通过this访问到$message然后就可以弹框提示了同时$message身上提供了一些弹框方法error('失败')、success('成功')我们只需要调用这些方法,提示需要的信息就可以了。

Login.vue中,调用这些方法:

  登录成功:this.$message.error('登录失败')登录失败:this.$message.success('登录成功')

2.实现登录

​ ①通过 axios 调用登录验证接口

​ ②登录成功之后保持用户 token 信息

​ ③跳转到项目主页

在Login.vue中:

 this.$message.success('登录成功')// 1.将登录成功之后的token,保存到客户端的sessionStorage中//   localstorage   是持久化的存储机制//   sessionStorage 是会话期间的存储机制//      1.1 项目中除了登录之外的其他API接口,必须在登录之后才能访问//      1.2 token只应在当前网站打开期间生效,所以将token保存在sessionStorage中
第一步: window.sessionStorage.setItem("token",res.data.token);// 2.通过编程式导航跳转到后台主页,路由地址是 /home
第二步: this.$router.push('/home');

然后在components文件夹下,新建Home.vue

<template><div>Home 组件</div>
</template><script>
export default {}
</script><style lang="less" scoped></style>

接着在router.js导入home组件,添加路由规则

// 导入home组件
import Home from './components/Home.vue'
// 添加路由规则
{ path: '/home',component: Home }

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

需求:/home页面属于有权限的页面

  1. 只有用户在登录的情况下才允许访问,如果是未登录状态是不允许看到home页面的
  2. 如果用户没有登录,希望用户从home路径直接跳转到登录页

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

**在router.js中,添加路由导航守卫 router.beforeEach **

 // 为路由对象,添加 beforeEach 函数(导航守卫) to表示将要访问的页面路径;from表示从哪个路径跳转到哪个路径next表示放行的函数const router = new Router({})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')// 经过判断用户有token值,直接放行next()})export default router**通过用户访问的地址以及用户是否有token值,来决定用户具体访问的是哪个页面。**

退出功能实现原理

基于 token 的方式实现退出比较简单,只需要销毁本地的 token ,利用编程式导航–重新返回登录页面。

这样,后续的请求就不会携带 token ,必须重新登录生成一个新的 token 之后才可以访问页面。

在Home.vue组件中:

<template><div>第一步:<el-button type="info" @click="logout">退出</el-button></div>
</template><script>export default {
第二步:methods:{logout(){window.sessionStorage.clear();this.$router.push("/login");}}}
</script><style lang="less" scoped></style>

登录页面 login.vue

完整代码示例:

<template><dir class="login_container"><div class="login_box"><!-- 头部图片区域 --><div class="avator_box"><img src="../assets/logo.png" alt /></div><!-- 表单区域 --><el-form class="login_form" :model="loginForm" :rules="loginFormRules" ref="loginFormRef"><!-- 用户名 --><el-form-item prop="username"><el-input v-model="loginForm.username" prefix-icon="iconfont icon-user"></el-input></el-form-item><!-- 密码 --><el-form-item prop="username"><el-inputtype="password"v-model="loginForm.password"prefix-icon="iconfont icon-3702mima"></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></dir>
</template><script>
export default {data () {return {// 表单的数据绑定loginForm: {username: 'admin',password: '123456'},// 表单的数据验证loginFormRules: {username: [{ required: true, message: '请输入用户名', trigger: 'blur' },{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }],password: [{ required: true, message: '请输入密码', trigger: 'blur' },{ min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }]}}},methods: {// 重置按钮resetLoginForm () {console.log(this)this.$refs.loginFormRef.resetFields()},// 登录按钮login () {// 实现登录前表单的预验证this.$refs.loginFormRef.validate(async valid => {console.log(valid)if (!valid) return// 验证通过--执行登录操作const { data: res } = await this.$http.post('/login', this.loginForm)console.log(res)if (res.meta.status !== 200) return this.$message.error('登录失败')this.$message.success('登录成功')// 登录成功:保存token、跳转主页window.sessionStorage.setItem('token', res.data.token)this.$router.push('/home')})}}
}
</script><style lang="less" scoped>
.login_container {height: 100%;background-color: #006695;.login_box {width: 450px;height: 300px;background-color: #fff;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);.avator_box {width: 130px;height: 130px;border: 1px solid #ccc;border-radius: 50%;padding: 10px;box-shadow: 0 0 10px #ddd;background-color: #fff;position: absolute;left: 50%;transform: translate(-50%, -50%);img {width: 100%;height: 100%;border-radius: 50%;background-color: #eee;}}}.login_form {position: absolute;bottom: 0;width: 100%;padding: 0 10px;box-sizing: border-box;.btns {display: flex;justify-content: flex-end;}}
}
</style>

功能:登录和退出(表单重置和预验证、路由导航守卫、路由重定向)相关推荐

  1. vue + element-ui 对登录功能、重置表单、退出功能、路由重定向、挂载路由导航守卫的实现

    vue + element-ui 对登录功能.重置表单.退出功能.路由重定向.挂载路由导航守卫的实现 表单验证规则: 重置表单 和 对登录功能的验证: 路由重定向: 挂载路由导航守卫: 退出功能的实现 ...

  2. ElementUI实现el-form表单重置功能按钮

    目录 业务场景: 效果演示: 业务场景: 使用el-form时,点击重置按钮或者取消按钮时会实现表单重置效果. 重置功能按钮功能实现详细步骤: 第一:首先给el-form添加ref属性. <el ...

  3. Flask项目实战——7—(Redis数据库存储验证码信息、验证登录界面的表单信息、注册功能实现、登录实现)

    推荐一个API平台:聚合数据 1.Redis数据库存储验证码信息 保存手机验证码到Redis数据库 公有视图文件:apps/common/views.py # -*- encoding: utf-8 ...

  4. ElementUI 之el-form表单重置功能按钮

    业务场景: 使用el-form时,点击重置按钮或者取消按钮时会实现表单重置效果. 重置功能按钮功能实现详细步骤: 第一:首先给el-form添加ref属性. <el-form :inline=& ...

  5. 登录滑块验证表单_如何构建双滑块登录和注册表单

    登录滑块验证表单 Some of you might already know but for those who don't, I'm starting a Weekly Coding Challe ...

  6. ElementUI中el-form实现表单重置以及将方法抽出为全局方法

    场景 使用el-form时,点击重置按钮或者取消按钮时会实现表单重置效果. 那么el-form怎样实现表单重置,如果在多个页面需要用到重置,怎样将此方法抽出为全局的方法,在需要用到的地方直接引用. 注 ...

  7. 工作177:表单重置项目处理

    <template><!--新建账号对话框--><el-dialog title="新建账号" :visible.sync="dialogF ...

  8. php判断post是否xss,PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】...

    本文实例讲述了PHP实现表单提交数据的验证处理功能.分享给大家供大家参考,具体如下: 防XSS攻击代码: /** * 安全过滤函数 * * @param $string * @return strin ...

  9. 免费 PSD 下载: 20个精美的登录和注册表单

    注册表单有许多不同的形状和尺寸,有的只是单个的输入框,有的则需要多个步骤.登录表单的设计将定义网站的性质,因此它应进行针对性的设计.下面的列表提供了20个醒目的登录和注册表单设计为您提供灵感. Reb ...

最新文章

  1. 41岁程序员被裁,北京有1500万房产,程序员:我该不该退休?
  2. IIS 6和IIS 7 中设置文件上传大小限制设置方法,两者是不一样的
  3. 有关弹窗页面的注意问题
  4. 搜集来的命令集合,挺好的
  5. GraphPad Prism 9.2 科学绘图 最新 可用
  6. 每个Java应用容器都要包含tomcat_部署一个不依赖tomcat容器的应用
  7. Python之路【第十五篇】:Web框架
  8. nginx源码分析——filter模块
  9. docker挂载目录
  10. 下载徐小明新浪博客全部博文链接
  11. Synergy让一个鼠标一个键盘操作多台电脑
  12. 我在小公司,当了五年的前端切图仔
  13. 陆丰市福山妈祖:四大天王
  14. 《SegStereo: Exploiting Semantic Information for Disparity Estimation》
  15. 中国二线城市有哪些比较知名的芯片设计企业
  16. 想备战 2022 ‘金三银四’ 必备超多软件测试面试题全在这里
  17. HbuilderX下载安装教程
  18. 集合框架|Java集合框架基本使用
  19. 原码一位乘、补码一位乘(校正法、布斯法)、补码两位乘
  20. 基于Python的k均值聚类不同规格的商品名

热门文章

  1. 魅族会使用鸿蒙系统,小米、OV傻眼,魅族要用鸿蒙系统!
  2. 笔记本电脑为什么关不了机
  3. 电容或电感的电压_【这观点我服】升压PFC电感上面的二极管的真正作用!
  4. 北京人交满15年社保,最后你能拿到多少养老金?算完忍不住笑了!
  5. 如何恢复丢失Iphone系列手机内置资料
  6. 京东电器“220V带电新人类”:找寻狂拽炫酷吊炸天的科技感
  7. php根据日期判断星座if函数,js 日期计算星座 根据生日的月份和日期,一行代码计算星座的js小函数(转)...
  8. Java北京时间与UTC世界标准时间之间的相互转换
  9. 家好人团圆 中秋佳节 四款新游戏
  10. 2023年1、2月份回顾:比特币收涨41.7%,最大振幅53.6%