今日目标
- 能够利用
ajaxPrefilter
统一设置请求头 - 完成获取用户信息功能
- 能够利用
ajaxPrefilter
统一控制用户访问权限 - 能够完成基本资料的功能
- 能够完成重置密码功能
- 能够完成更换头像功能
- 参照文档使用
cropper
图片裁剪功能 - 知道
base64
格式图片的优缺点 - 利用
layer.open
自定义弹出层效果
一、后台主页
1、获取用户基本信息
在用户登录成功,进入后台页面后,我们应该立刻获取用户的信息,然后把对应的信息展示在页面上
- 在后台的
index.html
页面中引入需要的js
文件
<!-- 导入 jQuery --> <script src="/assets/lib/jquery.js"></script> <!-- 导入自己封装的 baseAPI --> <script src="/assets/js/baseAPI.js"></script> <!-- 导入自己的 js 文件 --> <script src="/assets/js/index.js"></script>
- 定义
getUserInfo
函数,当页面加载完毕之后调用这个函数 - 利用
$.ajax()
进行网络请求,查阅文档,获取关键信息
- 我们请求的时候就需要设置请求头信息,把我们获取到的
token
传递给后台 - 数据获取失败提示用户
js 代码( /assets/js/index.js )
$(function () { getUserInfo(); }); const layer = layui.layer; // 获取用户信息 function getUserInfo() { $.ajax({ type: "GET", url: "/my/userinfo", headers: { Authorization: localStorage.getItem("token"), }, success: (res) => { console.log(res); if (res.status !== 0) return layer.msg("获取用户信息失败!"); layer.msg("获取用户信息成功!"); }, }); }
2、渲染用户头像和名称
如果请求成功,我们根据服务器返回的数据来渲染页面
- 定义
renderAvatar
函数,接收服务器返回的用户数据 - 获取用户的名称
- 设置欢迎的文本,找到关键元素进行设置
- 按需渲染用户的头像,如果用户有头像,那么就直接设置图片头像,如果没有设置文本头像
js 代码( /assets/js/index.js )
// 渲染用户头像 const renderAvatar = (user) => { // 获取用户名字 let name = user.nickname || user.username; // 设置欢迎文本 $("#welcome").html(`欢迎 ${name}`); // 按需渲染用户头像 if (user.user_pic !== null) { // 渲染图片头像 $(".layui-nav-img").attr("src", user.user_pic).show(); $(".text-avatar").hide(); } else { // 渲染文本头像 $(".layui-nav-img").hide(); let firstName = name[0].toUpperCase(); $(".text-avatar").html(firstName); } };
3、统一为有权限的接口设置 headers
请求头
还记得之前的 ajaxPrefilter
函数吗,在我们调用 $.ajax()
后,并且在请求服务器之前调用的过滤器,那么我们能统一设置根路径,那么我们就可以去统一设置请求头
- 在
baseAPI
的ajaxPrefilter
中添加如下代码 - 判断
url
里面是否携带/my/
- 如果携带,那么我们就设置
options.headers
js 代码( /assets/js/baseAPI.js )
// 统一为有权限的接口,设置 headers 请求头 if (option.url.indexOf("/my/")) { option.headers = { Authorization: localStorage.getItem("token"), }; }
4、实现退出功能
- 给退出按钮绑定点击事件,取消
a
标签的默认行为 - 用户点击后,弹出提示框(
layui
中有弹出层的相关代码),如果用户点击确认
- 移除本地缓存的 token,并且跳转到登录页面
js 代码( /assets/js/index.js )
// 退出登录 $("#btnLogout").click(() => { layui.layer.confirm( "确定退出登录?", { icon: 3, title: "" }, function (index) { // 清空本地存储里面的 token localStorage.removeItem("token"); // 重新跳转到登录页面 location.href = "/login.html"; } ); });
5、控制用户的访问权限
用户如果没有登录,是否能够允许用户访问后台主页?肯定是不能的,所以我们需要进行权限的校验,可以利用请求后服务器返回的状态来决定
- 在调用有权限接口的时候,指定
complete
回调函数,这个回调函数不管成功还是失败都会调用 - 在回调里面判断 服务器返回的的状态是否等于 1,并且错误的信息是 “身份认证失败”,如果成立,那么就强制用户跳转到登录页
js 代码( /assets/js/index.js )
// 不论成功还是失败,最终都会调用 complete 回调函数 complete: (res) => { // 在 complete 回调函数中,可以使用 res.responseJSON 拿到服务器响应回来的数据 if(res.responseJSON.status ===1 && res.responseJSON.message === "身份认证失败!") { // 强制清空 token localStorage.removeItem("token"); // 强制跳转到登录页面 location.href = "/login.html" } },
6、优化权限控制的代码
目前有一个问题,每一个权限的请求难道都需要去判断一次 complete的逻辑代码吗?借助统一设置请求根路径和请求头的思路,我们也可以统一来设置 complete 函数
- 将权限控制的代码,从每个请求中,抽离到
ajaxPrefilter
中 - 利用
options
来挂在统一的complete
函数
js 代码( /assets/js/baseAPI.js )
option.complete = (res) => { // 在 complete 回调函数中,可以使用 res.responseJSON 拿到服务器响应回来的数据 if(res.responseJSON.status ===1 && res.responseJSON.message === "身份认证失败!") { // 强制清空 token localStorage.removeItem("token"); // 强制跳转到登录页面 location.href = "/login.html" } }
7、将本地代码同步到云端
git status
查看文件状态git branch
查看分支git add .
添加到暂存区git commit -m 提交消息
git push -u origin index
推送到远程分支git checkout master
切换到主分支git merge index
合并分支git push
推送到云端git checkout -b user
创建 user 分支
二、基本资料
1、创建基本资料对应的页面
- 新建一个
user
文件夹 - 新建
/user/user_info.html
页面 - 在
index.html
里面指定,点击对应的a
标签要打开的页面,并且指定在哪里进行打开
<a href="/user/user_info.html" target="fm"><i class="layui-icon layui-icon-app"></i>基本资料</a>
- 搭建页面结构,利用
layui
的卡片的组件来实现
html 结构( /user/user_info.html )
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <link rel="stylesheet" href="/assets/lib/layui/css/layui.css"> <link rel="stylesheet" href="/assets/css/user/user_info.css" /> </head> <body> <div class="layui-card"> <div class="layui-card-header">修改用户信息</div> <div class="layui-card-body"> 卡片式面板面板通常用于非白色背景色的主体内<br /> 从而映衬出边框投影 </div> </div> </body> </html>
css 样式( /assets/css/user/user_info.css )
html, body { margin: 0; padding: 0; } body { background-color: #f2f3f5; padding: 15px; }
2、绘制基本资料对应的表单
- 利用
layui
中表单元素来搭建 - 一共使用 三个 input 输入框的结构
- 还需要一个 提交按钮 和 重置按钮
html 结构( /user/user_info.html )
<!-- form 表单 --> <form class="layui-form" action=""> <div class="layui-form-item"> <label class="layui-form-label">登录名称</label> <div class="layui-input-block"> <input type="text" name="username" required readonly lay-verify="required" placeholder="请输入登录名称" autocomplete="off" class="layui-input" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">用户昵称</label> <div class="layui-input-block"> <input type="text" name="nickname" required lay-verify="required|nickname" placeholder="请输入用户昵称" autocomplete="off" class="layui-input" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">用户邮箱</label> <div class="layui-input-block"> <input type="text" name="email" required lay-verify="required|email" placeholder="请输入用户邮箱" autocomplete="off" class="layui-input" /> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit lay-filter="formDemo">提交修改</button> <button type="reset" class="layui-btn layui-btn-primary">重置</button> </div> </div> </form>
在页面底部导入如下的脚本
<script src="/assets/lib/layui/layui.all.js"></script> <script src="/assets/lib/jquery.js"></script> <script src="/assets/js/baseAPI.js"></script> <script src="/assets/js/user/userinfo.js"></script>
js 代码( /assets/js/user/userinfo.js )
$(function() { const form = layui.form; // 自定义校验规则 form.verify({ nickname: (val) => { if (val.length > 6) return "昵称长度必须在 1 ~ 6 个字符之间!"; }, }); })
3、获取用户的基本信息
- 导入
baseAPI
- 在
user_info.js
中定义并调用initUserInfo
函数 - 在
initUserInfo
函数中 调用$.ajax()
获取用户基本信息 - 如果返回的 status 为0,那么代表成功,如果不等于,代表失败,利用
layer
进行提示
js 代码( /assets/js/user/userinfo.js )
const layer = layui.layer; // 初始化用户信息 const initUserInfo = () => { $.ajax({ type: "GET", url: "/my/userinfo", success: (res) => { if (res.status !== 0) return layer.msg("获取用户信息失败!"); console.log(res); }, }); }; initUserInfo();
4、为表单快速赋值
利用 form.val()
进行快速赋值,赋值之前我们需要给 form
表单添加 一个 lay-filter
的属性
- 为表单指定
lay-filter
属性
<form class="layui-form" action="" lay-filter="formUserInfo"></form>
- 调用
form.val()
方法为表单赋值
form.val("formUserInfo", res.data);
- 使用隐藏域保存用户的
id
值
<form class="layui-form" action="" lay-filter="formUserInfo"> <!-- 隐藏域 --> <input type="hidden" name="id"> <!-- 省略其他代码 --> </form>
5、实现表单的重置效果
用户点击了重置按钮后,表单里面的内容应该被重置
- 阻止表单的默认重置行为
- 重新调用
initUserInfo()
函数,重新获取用户信息
js 代码( /assets/js/user/userinfo.js )
// 重置表单数据 $("#btnReset").click((e) => { e.preventDefault(); initUserInfo() });
6、发起请求更新用户的信息
- 监听表单提交事件,在事件处理函数里面取消默认行为
- 查阅接口文档,利用
$.ajax()
发起post
请求 - 利用
$(this).serialize()
获取表单数据 - 如果返回的 status 不为0,说明更新失败,及逆行提示
- 更新成功之后,调用父页面中的方法,重新渲染用户的头像和用户信息
js 代码( /assets/js/user/userinfo.js )
// 更新用户数据 $(".layui-form").on("submit", (e) => { e.preventDefault(); $.ajax({ type: "POST", url: "/my/userinfo", data: $(".layui-form").serialize(), success: (res) => { if (res.status !== 0) return layer.msg("更新用户信息失败!"); layer.msg("更新用户信息成功!"); // 调用父页面渲染函数 window.parent.getUserInfo(); }, }); });
三、重置密码
1、渲染重置密码的页面结构
- 新建重置密码的页面,
user_pwd.html
,给侧边栏对应a标签设置href
的路径,以及target
属性 - 利用
layui
的卡片(页面元素 > 面板 > 卡片布局) 搭建结构 - 利用
layui
的表单元素(页面元素 > 表单)来搭建里面内容 - 修改下里面的文字内容
html 结构( /user/user_pwd.html )
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <link rel="stylesheet" href="/assets/lib/layui/css/layui.css" /> <link rel="stylesheet" href="/assets/css/user/user_pwd.css" /> </head> <body> <div class="layui-card"> <div class="layui-card-header">修改密码</div> <div class="layui-card-body"> <form class="layui-form" action=""> <div class="layui-form-item"> <label class="layui-form-label">原密码</label> <div class="layui-input-block"> <input type="password" name="oldPwd" required lay-verify="required" placeholder="请输入原密码" autocomplete="off" class="layui-input" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">新密码</label> <div class="layui-input-block"> <input type="password" name="newPwd" required lay-verify="required" placeholder="请输入新密码" autocomplete="off" class="layui-input" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">请确认密码</label> <div class="layui-input-block"> <input type="password" name="rePwd" required lay-verify="required" placeholder="请再次确认密码" autocomplete="off" class="layui-input" /> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit lay-filter="formDemo"> 立即提交 </button> <button type="reset" class="layui-btn layui-btn-primary"> 重置 </button> </div> </div> </form> </div> </div> </body> </html>
css 样式( /assets/css/user/user_pwd.css )
html, body { margin: 0; padding: 0; } body { padding: 15px; background-color: #f2f3f5; } .layui-form { width: 500px; }
2、为密码框定义校验规则
导入相关js
脚本
<!-- 导入 layui 的 js --> <script src="/assets/lib/layui/layui.all.js"></script> <!-- 导入 jQuery --> <script src="/assets/lib/jquery.js"></script> <!-- 导入 baseAPI --> <script src="/assets/js/baseAPI.js"></script> <!-- 导入自己的 js --> <script src="/assets/js/user/user_pwd.js"></script>
- 导入 form 模块
- 利用
form.verify()
来定义规则
- 长度必须是6到12位
- 不能与旧密码一致
- 两次密码是否相同
- 在对应的表单元素中,利用
lay-verify
来设置自定义校验规则
js 代码( /assets/js/user/userpwd.js )
const form = layui.form; form.verify({ pwd: [/^[\S]{6,12}$/, "密码必须6到12位,且不能出现空格"], samePwd: (val) => { if (val === $("[name=oldPwd]").val()) return "新旧密码不能相同!"; }, rePwd: (val) => { if (val !== $("[name=newPwd]").val()) return "两次密码不一致!"; }, });
- 为密码框分别添加对应的校验规则
html 结构( /user/user_pwd.html )
<form class="layui-form" action=""> <div class="layui-form-item"> <label class="layui-form-label">原密码</label> <div class="layui-input-block"> <input type="password" name="oldPwd" required lay-verify="required|pwd" placeholder="请输入原密码" autocomplete="off" class="layui-input" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">新密码</label> <div class="layui-input-block"> <input type="password" name="newPwd" required lay-verify="required|pwd|samePwd" placeholder="请输入新密码" autocomplete="off" class="layui-input" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">请确认密码</label> <div class="layui-input-block"> <input type="password" name="rePwd" required lay-verify="required|pwd|rePwd" placeholder="请再次确认密码" autocomplete="off" class="layui-input" /> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit lay-filter="formDemo"> 立即提交 </button> <button type="reset" class="layui-btn layui-btn-primary"> 重置 </button> </div> </div> </form>
3、发起请求实现重置密码的功能
- 给form表单绑定 submit 事件,在事件处理函数里面取消默认行为
- 查阅接口文档,利用
$.ajax()
来发送post
请求 - 利用
$(this).serialize()
来设置提交的数据 - 如果 服务器返回的
status
不等于0,说明失败,利用 layui.layer.msg
来进行提示 - 如果更新成功,重置一下表单内容
js 代码( /assets/js/user/userpwd.js )
const layer = layui.layer; // 发送请求,重置密码 $(".layui-form").on("submit", (e) => { e.preventDefault(); $.ajax({ type: "POST", url: "/my/updatepwd", data: $(".layui-form").serialize(), success: (res) => { if (res.status !== 0) return layer.msg("更新密码失败!"); layer.msg("更新密码成功!"); // 重置表单 $(".layui-form")[0].reset(); }, }); });