大事件项目第二天

5 篇文章 1 订阅
3 篇文章 1 订阅


今日目标

  • 能够利用 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() 后,并且在请求服务器之前调用的过滤器,那么我们能统一设置根路径,那么我们就可以去统一设置请求头

  • baseAPIajaxPrefilter 中添加如下代码
  • 判断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();
        },
    });
});
四、更换头像

在这里插入图片描述

1、初步渲染更换头像页面的结构
  • 创建 /user/user_avatar.html 页面
  • 放入卡片区域 (页面元素 > 面板 > 卡片),修改对应文字信息
  • 在侧边栏对应的 a 标签设置 href 属性 和 target 属性

html 结构( /user/user_avatar.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_avatar.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_avatar.css )

html,
body {
    margin: 0;
    padding: 0;
}

body {
    padding: 15px;
    background-color: #f2f3f5;
}

修改 index.html 中对应链接的属性

<a href="/user/user_avatar.html" target="fm"><i class="layui-icon layui-icon-app"></i>更换头像</a>
2、实现裁剪区域图片的替换
  • <head> 中导入 cropper.css 样式表:
<link rel="stylesheet" href="/assets/lib/cropper/cropper.css" />
  • <body>的结束标签之前,按顺序导入如下的 js 脚本
<script src="/assets/lib/jquery.js"></script>
<script src="/assets/lib/cropper/Cropper.js"></script>
<script src="/assets/lib/cropper/jquery-cropper.js"></script>
  • 在卡片的 layui-card-body 主体区域中,定义如下的 HTML 结构

html 结构( /user/user_avatar.html )

<!-- 第一行的图片裁剪和预览区域 -->
<div class="row1">
    <!-- 图片裁剪区域 -->
    <div class="cropper-box">
        <!-- 这个 img 标签很重要,将来会把它初始化为裁剪区域 -->
        <img id="image" src="/assets/images/sample.jpg" />
    </div>
    <!-- 图片的预览区域 -->
    <div class="preview-box">
        <div>
            <!-- 宽高为 100px 的预览区域 -->
            <div class="img-preview w100"></div>
            <p class="size">100 x 100</p>
        </div>
        <div>
            <!-- 宽高为 50px 的预览区域 -->
            <div class="img-preview w50"></div>
            <p class="size">50 x 50</p>
        </div>
    </div>
</div>
    <!-- 第二行的按钮区域 -->
    <div class="row2">
        <button type="button" class="layui-btn">上传</button>
        <button type="button" class="layui-btn layui-btn-danger">确定</button>
    </div>
  • 美化的样式

css 样式( /assets/css/user/user_avatar.css )

/* 设置卡片主体区域的宽度 */
.layui-card-body {
  width: 500px;
}

/* 设置按钮行的样式 */
.row2 {
  display: flex;
  justify-content: flex-end;
  margin-top: 20px;
}

/* 设置裁剪区域的样式 */
.cropper-box {
  width: 350px;
  height: 350px;
  background-color: cyan;
  overflow: hidden;
}

/* 设置第一个预览区域的样式 */
.w100 {
  width: 100px;
  height: 100px;
  background-color: gray;
}

/* 设置第二个预览区域的样式 */
.w50 {
  width: 50px;
  height: 50px;
  background-color: gray;
  margin-top: 50px;
}

/* 设置预览区域下方文本的样式 */
.size {
  font-size: 12px;
  color: gray;
  text-align: center;
}

/* 设置图片行的样式 */
.row1 {
  display: flex;
}

/* 设置 preview-box 区域的的样式 */
.preview-box {
  display: flex;
  flex-direction: column;
  flex: 1;
  align-items: center;
}

/* 设置 img-preview 区域的样式 */
.img-preview {
  overflow: hidden;
  border-radius: 50%;
}
  • 实现基本裁剪效果

    • 获取裁剪区域的 DOM 元素

    • 配置选项: 纵横比、指定预览区域

    • 创建裁剪区域

js 代码( /assets/js/user/useravatar.js )

// 1.1 获取裁剪区域的 DOM 元素
var $image = $('#image')
// 1.2 配置选项
const options = {
  // 纵横比
  aspectRatio: 1,
  // 指定预览区域
  preview: '.img-preview'
}

// 1.3 创建裁剪区域
$image.cropper(options)
3、点击弹出文件选择框

默认的文件选择框样式比较丑,所以我们定义这个结构,让其隐藏,给文件选择框指定可以上传的文件类型

html 结构( /user/user_avatar.html )

<input type="file" id="file" accept="image/png,image/jpeg" />

隐藏文件上传框

css 样式( /assets/css/user/user_avatar.css )

/* 隐藏文件上传框 */
#file {
    display: none;
}

下面定义一个按钮,文本是 上传,一旦用户点击按钮,我们手动触发 文件选择框的点击事件

js 代码( /assets/js/user/user_avatar.js )

$('#btnChooseImage').on('click', function() {
  $('#file').click()
})
4、 更换裁剪区域的图片
  • 给文件选择框绑定 change 事件
  • 用户选择了文件就会触发这个事件,通过 e.target.files 获取用户选择文件列表
  • 通过索引0拿到用户选择的文件
  • 将文件转化为路径
  • 利用 $image 重新初始化裁剪区域

先引入 layui 提供的 js 文件

html 结构( /user/user_avatar.html )

<script src="/assets/lib/layui/layui.all.js"></script>

js 代码( /assets/js/user/useravatar.js )

const layer = layui.layer;

// 为文件上传框绑定 change 事件
$("#file").change((e) => {
    const fileList = e.target.files.length;
    if (fileList === 0) return layer.msg("请选择文件!");

    // 1. 拿到用户选择的文件
    let file = e.target.files[0];
    // 2. 将文件,转化为路径
    var imgURL = URL.createObjectURL(file);
    // 3. 重新初始化裁剪区域
    $image
        .cropper("destroy") // 销毁旧的裁剪区域
        .attr("src", imgURL) // 重新设置图片路径
        .cropper(options); // 重新初始化裁剪区域
});
5、将裁剪后的头像上传到服务器
  • 为确定按钮,绑定点击事件
  • 要拿到用户裁剪之后的头像
    • 创建一个 Canvas 画布,将 Canvas 画布上的内容,转化为 base64 格式的字符串

引入 basePI.js 文件

html 结构( /user/user_avatar.html )

<script src="/assets/js/baseAPI.js"></script>

js 代码( /assets/js/user/useravatar.js )

//  为确定按钮绑定点击事件
$("#btnUpload").click(() => {
    // 1、拿到用户裁切之后的头像
    // 直接复制代码即可
    const dataURL = $image.cropper("getCroppedCanvas", {
        // 创建一个 Canvas 画布
        width: 100,
        height: 100,
    })
    .toDataURL("image/png");
    // 2、发送 ajax 请求,发送到服务器
    $.ajax({
        method: "POST",
        url: "/my/update/avatar",
        data: {
            avatar: dataURL,
        },
        success: function (res) {
            if (res.status !== 0) {
                return layer.msg("更换头像失败!");
            }
            layer.msg("更换头像成功!");
            window.parent.getUserInfo();
        },
    });
});
6、了解base64格式的图片

base64格式你会发现是一段字符串,其实base64格式的图片,就是利用一段字符串来描述这张图片

好处:能够避免一些额外的图片请求

缺点:体积会比原来图片要大 30% 左右

使用场景:不适用大图片,一些小图片比较适合使用

7、设置头部区域的快捷方式

打开 index.html,修改头部 个人中心 下的三个快捷方式如下:

html 结构( /index.html )

<dl class="layui-nav-child">
    <dd><a href="/user/user_info.html" target="fm">基本资料</a></dd>
    <dd><a href="/user/user_avatar.html" target="fm">更换头像</a></dd>
    <dd><a href="/user/user_pwd.html" target="fm">重置密码</a></dd>
</dl>
8、本地代码推送到 github
  • git branch 查看一下分支
  • git add . 添加到暂存区
  • git commit -m 进行提交到本地仓库
  • git push -u origin user 推送到远程仓库的user分支
  • git checkout master 切换到主分支
  • git merge user 合并分支
  • git push 推送到远程仓库的主分支
五、文章分类

在这里插入图片描述

1、 创建并显示文章分类页面

创建 /article/art_cate.html 页面,并初始化如下的UI结构

html 结构( /article/art_cate.html )

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <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/article/art_cate.css" />
    </head>
    <body>
        <!-- 卡片区域 -->
        <div class="layui-card">
            <div class="layui-card-header">
                <span>文章类别管理</span>
            </div>
            <div class="layui-card-body">
                <table class="layui-table">
                    <colgroup>
                        <col />
                        <col />
                        <col width="200" />
                    </colgroup>
                    <thead>
                        <tr>
                            <th>分类名称</th>
                            <th>分类别名</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>贤心</td>
                            <td>2016-11-29</td>
                            <td>人生就像是一场修行</td>
                        </tr>
                        <tr>
                            <td>许闲心</td>
                            <td>2016-11-28</td>
                            <td>于千万人之中遇见你所遇见的人,于千万年之中,时间的无涯的荒野里…</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </body>
</html>

css 样式( /assets/css/article/art_cate.css )

html,
body {
    margin: 0;
    padding: 0;
}

body {
    padding: 15px;
    background-color: #f2f3f5;
}
2、快速绘制文章类别页面的基本结构
  • layui-card-header里面添加右侧的按钮
  • layui-card-header 设置成flex 布局,让里面内容两侧对齐 justify-content: space-between

html 结构( /article/art_cate.html )

<div class="layui-card-header">
    <span>文章类别管理</span>
    <button type="button" class="layui-btn layui-btn-normal layui-btn-sm">添加类别</button>
</div>

css 样式( /assets/css/article/art_cate.css )

.layui-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
3、获取并使用模板引擎渲染表格的数据
  • 利用模板引擎来进行渲染
  • 在页面底部导入模板引擎

导入所需要的 js 文件

html 结构( /article/art_cate.html )

<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/lib/template-web.js"></script>
<script src="/assets/js/article/art_cate.js"></script>

设置 template 模板

html 结构( /article/art_cate.html )

<!-- 定义模板 -->
<script type="text/html" id="tpl-table">
    {{each data}}
      <tr>
        <td>{{$value.name}}</td>
        <td>{{$value.alias}}</td>
        <td>
          <button type="button" class="layui-btn layui-btn-xs">编辑</button>
          <button type="button" class="layui-btn layui-btn-danger layui-btn-xs">删除</button>    
    </td>
    </tr>
    {{/each}}
</script>

发起数据请求

js 代码( /assets/js/article/art_cate.js )

$(function() {
    // 获取 表格数据
    const initArtCateList = () => {
        $.ajax({
            type: "GET",
            url: "/my/article/cates",
            success: (res) => {
                // 调用 template
                const htmlStr = template("tpl-table", res);
                $("tbody").empty().html(htmlStr);
            },
        });
    };

    initArtCateList();
})
4、使用layer.open实现弹出层效果

为按钮添加 id 属性

html 结构( /article/art_cate.html )

<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" id="btnAddCate">添加类别</button>

在按钮的点击事件中,通过 layer.open() 展示弹出层

js 代码( /assets/js/article/art_cate.js )

const layer = layui.layer;

$("#btnAddCate").click(() => {
    layer.open({
        type: 1,
        area: ["500px", "250px"],
        title: "添加文章分类",
        content: "ABC",
    });
});
5、 在弹出层中渲染form表单结构

利用模板引擎的思路,在页面中定义如下的 script 标签

html 结构( /article/art_cate.html )

<!-- 定义弹出层模板 -->
<script type="text/html" id="dialog-add">
    <form class="layui-form" id="form-add">
      <div class="layui-form-item">
        <label class="layui-form-label">分类名称</label>
        <div class="layui-input-block">
          <input type="text" name="name" 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="text" name="alias" 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>
</script>

修改 form 表单样式

css 样式( /assets/css/article/art_cate.css )

#form-add {
  padding-top: 20px;
  padding-right: 30px;
}

通过 content 属性指定内容

js 代码( /assets/js/article/art_cate.js )

layer.open({
    type: 1,
    area: ['500px', '250px'],
    title: '添加文章分类',
    content: $('#dialog-add').html()
})
6、实现添加文章分类的功能

发起Ajax请求,注意,我们这个按钮不是写死的,是弹框出来的时候动态生成的,所以我们通过事件委派方式给表单绑定 submit 事件

js 代码( /assets/js/article/art_cate.js )

// 通过代理监听 submit 事件
$("body").on("submit", "#form-add", function (e) {
    e.preventDefault();
    $.ajax({
        type: "POST",
        url: "/my/article/addcates",
        data: $(this).serialize(),
        success: (res) => {
            if (res.status !== 0) return layer.msg("新增分类失败!");
            initArtCateList();
            layer.msg("新增分类成功!");
            layer.close(indexAdd);
        },
    });
});

预先保存弹出层的索引,方便进行关闭

js 代码( /assets/js/article/art_cate.js )

let indexAdd = null;
$("#btnAddCate").click(() => {
    indexAdd = layer.open({
        type: 1,
        area: ["500px", "250px"],
        title: "添加文章分类",
        content: $("#dialog-add").html(),
    });
});
点击跳转第三天👉http://t.csdn.cn/eafVS
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itpeilibo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值