大事件项目

772 阅读11分钟

大事件项目纪要

1.注册功能

路由实现组件切换

  1. 新建两个页面组件

    在 views 下新建 Reg/Reg.vue 和 Login/Login.vue

  2. 在 router/index.js 中配置路由规则

  3. 在 App.vue 中使用 router-view 组件配置路由出口

  4. 在浏览器输入 http://localhost:8081/#/loginhttp://localhost:8081/#/reg 实现切换

渲染注册表单

  1. 去官网复制 form 组件的前四行, 补上结束标签
  2. 根据需求完善数据项的设置
  3. 美化样式

注册表单校验

  1. 检查复制过来的表单组件中重要的属性是否存在
    • model
    • rules
    • ref
    • prop (form-item)
  2. 在 rules 对象中写校验规则(复制官网代码进行修改)
  3. 注册按钮点击事件中做兜底校验

注册功能实现

  1. 通过兜底校验后发送 ajax 请求, 携带数据对象
  2. 获取服务器返回的结果后根据状态码进行判断, 并提示用户
  3. 注册成功后使用编程式导航跳转至登录页

2.登录功能

渲染登录页面和跳转注册

  1. el-link 添加点击事件, 编程式导航跳转至 /reg

点击按钮发起请求

  1. 给登录按钮绑定点击事件, 做兜底校验
  2. 如果通过校验就发起请求
  3. 获取请求结果, 进行判断并提示用户成功或失败

存储 token 至 Vuex

  1. store/index.js 中定义子模块及数据, 并开启命名空间
  2. 定义 mutation 函数, 用于修改 Vuex 中的 token
  3. 登录成功时触发 mutation 的函数, 并传递 token

token 持久化

  1. 手动 (自己实现)

    • 在 mutation 函数中使用 localStorage.setItem() 存储 token
    • 在 state 初始化值的时候使用 localStorage.getItem() 取出 token
  2. 插件 (自动实现)

    安装该插件后, 会自动持久化存储 Vuex 中所有的数据, 如需进行进一步的配置, 请查看官网

    • 下包 yarn add vuex-persistedstate
    • 导入
    • 安装插件

登录成功跳转至首页

  1. 登录成功后使用编程式导航跳转至 / 后台主页
  2. 配置路由规则, 新建 Main.vue 首页
  3. 将笔记中 Main.vue 的结构样式复制过来

退出登录

  1. 找到退出登录按钮, 给 menu-item 绑定点击事件
  2. 用户点击退出时使用 $confirm 确认框提醒用户是否真的要退出
  3. 用户确认退出时, 清空 Vuex 中的 token 并跳转至 /login 登录页

3.侧边栏菜单

渲染用户信息

  1. 去复制静态页面及 CSS 样式
  2. 在 Vuex 中定义 userInfo 数据
  3. actions 中封装一个获取用户信息的函数
  4. 发起请求获取用户信息 (通过 context 可以获取到 state)
  5. 将获取到的用户信息传递给 mutations 进行修改 userInfo
  6. Main.vue 的 created 中使用 this.$store.dispatch() 触发 actions 函数执行
  7. 将数据导入 Main.vue (使用辅助函数)
  8. 渲染数据

渲染侧边菜单布局

  1. 去官网复制 el-menu 的代码并进行学习
    • el-menu: 导航菜单容器
      • default-active: 默认高亮的菜单项
    • el-menu-item: 没有子菜单的项目
      • index: 菜单项的唯一标识
    • el-submenu: 有子菜单的项目
  2. 复制样式进行美化或自行补全

渲染侧边菜单数据

  1. 在 Main.vue 中封装 getMenus 函数, 在 created 中调用, 发起请求获取菜单数据并存入 data
  2. 由于循环渲染的菜单项有两种类型, 所以需要使用 template 标签包裹
  3. 在 template 标签上写 v-for 循环渲染
    • template 是虚拟标签, 不能绑定 key, 需要将 key 设置在子元素上
  4. 在两个子菜单标签上通过 v-if 进行判断具体显示哪个菜单项
  5. 使用插值表达式和 v-bind 动态渲染内容
    • 动态绑定 index 属性, 用于导航高亮
  6. el-submenu 还需要继续使用 v-for 渲染子菜单
  7. 开启路由模式方便后续开发

优化请求 token

  1. 在 main.js 中给 axios 添加请求拦截器
  2. 拦截时携带 token 给请求头
    • 在 main.js 中可以直接使用 store 对象获取到 Vuex 中的数据
  3. 之前手动携带 token 的地方可以删除请求头配置

权限控制

未登录禁止访问首页 - 导航守卫

  1. 在 router/index.js 中配置全局前置导航守卫
  2. 判断条件有 2 个需要进行拦截:
    1. 本地没有 token
    2. 不是访问 /login 和 /reg 页面时

已登录但 Token 过期 - axios 的响应拦截器

  1. 添加 axios 响应拦截器, 判断状态码为 401 的情况
  2. 给用户友好的提示
  3. 跳转至 /login 页面并清空 token 和 userInfo

渲染首页

  1. 创建 views/Menus/Home/Home.vue 组件, 复制笔记中的代码
  2. 观察代码发现需要 echarts, 所以下载 echarts 包
  3. 希望访问 /home 时切换到该组件显示, 配置 Main 的子路由
  4. 在 Main.vue 中写一个 router-view 作为路由出口
  5. 给 Main 路由规则配置重定向

4.个人中心 - 基本资料

使用路由渲染组件

  1. 创建 views/Menus/User/UserInfo.vue 组件, 复制笔记中的代码
  2. 配置路由规则, 同 Home 组件

渲染表单

  1. 去官网找到 form 组件进行复制
  2. 根据需求修改成项目需要的样式
  3. 在 UserInfo.vue 中导入辅助函数并映射 userInfo 数据
  4. 在 created 中将 userInfo 赋值给 userForm, 需要使用浅拷贝, 确保两个对象互不影响
  5. 在 userRules 中添加表单校验规则

重置表单

  1. 给重置按钮绑定点击事件
  2. 调用表单对象的 resetFields() 方法

更新用户信息

  1. 点击提交进行兜底校验
  2. 校验通过后发送请求更新用户信息
  3. 获取结果进行判断, 并提醒用户
  4. 如果更新成功, 重新发起请求获取最新的用户信息

5.个人中心 - 更换头像

使用路由渲染组件

  1. 创建 views/Menus/User/UserAvatar.vue 组件, 复制笔记中的代码
  2. 配置路由规则, 同上

选择图片

  1. 添加文件选择框在按钮上方, 但由于文件选择框太丑, 所以将其隐藏
  2. 给选择图片按钮绑定点击事件, 触发文件选择框的点击事件
  3. 给文件框绑定 change 事件
  4. 当用户选择图片时触发 change 事件, 并获取 e.target.files
  5. 根据 files 的长度来判断用户是否选择了图片

渲染预览图片

  1. 使用 FileReader 将 File 对象转换为 BASE64 字符串

    // 使用 FileReader 将 File 对象转换为 BASE64 并设置给 avatar
    // 创建 FileReader
    const fr = new FileReader()
    // 读取 File 对象
    fr.readAsDataURL(e.target.files[0])
    // 绑定事件, 必须使用箭头函数, 因为要访问 data 中的数据
    fr.onload = e => {
    // console.log(e.target.result)
    // 触发事件后赋值
    	this.avatar = e.target.result
    }
    
  2. 转换为 BASE64 后将字符串赋值给 avatar

  3. 准备两个 img 根据 avatar 的值进行 v-if 选择渲染

  4. 渲染完成后对上传按钮的 disabled 进行判断

更新用户头像

  1. 给按钮绑定点击事件, 发送请求携带 avatar 数据
  2. 根据响应的状态提示用户
  3. 重新获取用户信息

6.个人中心 - 修改密码

使用路由渲染组件

  1. 创建 views/Menus/User/UserPwd.vue 组件, 复制笔记中的代码
  2. 配置路由规则, 同上

表单校验

  1. 编写基础表单校验规则 (如果非常熟练可复制)
  2. 使用自定义校验规则进行两次密码相同校验

重置表单

  1. 给重置按钮绑定点击事件
  2. 调用表单对象的 resetFields() 方法

修改用户密码

  1. 给按钮绑定点击事件, 点击时进行兜底校验
  2. 校验通过后发起请求
  3. 获取结果并根据状态提示用户
  4. 重置表单

7.文章管理 - 文章分类

使用路由渲染组件

  1. 创建 views/Menus/Article/ArtCate.vue 组件, 复制笔记中的代码
  2. 配置路由规则, 同上

获取分类数据

  1. 在 created 中发起请求
  2. 获取数据判断结果
  3. 将数据存入 data 中

渲染表格

  1. 去 Element-UI 的官网复制表格代码
  2. 根据需求改造表格代码并渲染数据
    • table-column 设置 type 为 index 就是序号列
  3. 修改样式注意权重问题

渲染添加分类 Dialog

  1. 去 Element-UI 的官网复制最基础的 dialog 代码
  2. 根据需求修改绑定的数据和样式
  3. 在 dialog 中添加一个 form 组件, 两者结合使用
  4. 数据绑定并新增校验规则

关闭时重置表单

  1. 给 dialog 绑定事件: closed
  2. 事件触发时调用表单的重置方法即可

7.添加文章分类功能实现

  1. 给添加按钮绑定点击事件, 事件触发时进行兜底校验
  2. 校验通过后发起请求将用户输入的内容提交给后台
  3. 获取响应结果, 根据结果提醒用户
  4. 重新发起请求渲染页面
  5. 关闭 dialog

渲染修改分类 Dialog

  1. 将添加分类的 dialog 完整的复制一份
  2. 根据需求修改或添加所有的文本和数据变量
  3. 点击编辑按钮让 dialog 显示 (先不考虑功能实现, 仅做展示)
  4. 给编辑按钮绑定点击事件, 传入当前行数据 (作用域插槽: scope.row)
  5. 判断 id 是否为 1 或 2 并提醒用户不允许修改
  6. 将 row 浅拷贝给 editForm, 展示当前点击编辑的分类数据
  7. 将 editVisible 设置为 true (显示 dialog)

编辑文章分类功能实现

  1. 给确定按钮绑定点击事件, 事件触发时进行兜底校验
  2. 校验通过后发起请求将用户输入的内容提交给后台
  3. 获取响应结果, 根据结果提醒用户
  4. 重新发起请求渲染页面
  5. 关闭 dialog

删除文章分类

  1. 给删除按钮绑定点击事件, 传入 id
  2. 事件触发判断 id 是否为 1 或 2 并提醒用户不允许修改
  3. 发起请求给后台进行删除 (查询参数)
  4. 获取响应结果, 根据结果提醒用户
  5. 重新发起请求渲染页面

文章管理 - 发表文章

使用路由渲染组件

  1. 创建 views/Menus/Article/ArtList.vue 组件, 复制笔记中的代码
  2. 配置路由规则, 同上

弹出发表文章 Dialog

  1. 去 Element-UI 官网复制 Dialog 组件代码, 设置 fullscreen 属性变成全屏 dialog
  2. 绑定 :before-close 属性, 做关闭前的回调, 确保用户点击关闭不会直接关掉 dialog
  3. 当用户关闭时 this.$confirm 提醒用户, 是否确定关闭
  4. 如果确定关闭就关闭 dialog

渲染文章标题和文章分类表单

  1. 去 Element-UI 官网复制 Form 组件的代码
  2. 根据需求修改为我们想要的效果
  3. 双向绑定数据并设置表单校验规则

渲染文章分类数据

  1. 发送请求获取分类列表数据
  2. 使用 v-for 循环渲染 el-option
  3. 动态绑定 value 和 label

渲染富文本编辑器

  1. 下包 vue-quill-editor
  2. 按照官方文档导入并全局注册
  3. 使用组件, 并双向绑定数据
  4. 使用深度选择器修改样式 (min-height)
  5. 添加表单校验规则

渲染文章封面

  1. 去将静态结构复制到指定区域
  2. 添加 form-item
  3. 写 img 标签并修改样式
  4. 准备一个文件选择框, 将其设置为隐藏
  5. 准备一个按钮

用户选择图片

  1. 给选择封面按钮绑定点击事件, 用户点击时触发文件选择框的点击事件
  2. 给文件选择框绑定 change 事件
  3. 在 change 事件中使用事件对象获取用户选择的文件对象
  4. 判断用户选择的文件对象, 进行存储到表单或清空表单的封面图片

渲染预览图片

  1. 当用户选择图片后, 使用 FileReader 将图片对象转成 BASE64 字符串
  2. 设置给预览图片的 src
  3. 当用户取消选择后, 导入本地的默认图片, 将其设置给图片的 src

发布前准备工作

  1. 渲染两个按钮, 并绑定点击事件
  2. 事件触发时进行表单的兜底校验
  3. 通过校验后设置 state 为 '已发布''草稿'
  4. 关闭 dialog 时清空所有表单数据及预览的图片

发布文章

  1. 使用 FormData 填装参数
  2. 发起请求, 携带 FormData
  3. 根据结果提醒用户
  4. 关闭 dialog
  5. 将来实现了文章列表功能后, 还需要重新发请求获取最新的文章列表数据

文章管理 - 文章列表

渲染列表数据

  1. 封装获取列表数据的函数, 在 created 中调用获取数据存入 data 中
  2. 去 Element-UI 官网复制 Table 组件进行数据渲染
  3. 发表文章完成后, 调用封装的获取列表函数, 重新渲染页面

格式化日期

  1. 下包 dayjs
  2. 引入到组件中
  3. 封装一个 formatDate 的函数
  4. 在函数中格式化日期后返回
  5. 使用作用域插槽获取日期数据, 调用函数, 传入日期数据并使用插值表达式渲染

分页功能

  1. 去 Element-UI 官网复制 Pagination 组件
  2. 根据需求进行修改 (q.pagenum / q.pagesize / total)
  3. 获取数据时将 total 存入 data 中
  4. 结合 current-change 和 size-change 事件实现分页功能
  5. 当前页发生变化时将 q 的 pagenum 重新赋值并发起请求
  6. pagesize 同理

筛选功能

  1. 渲染文章分类的下拉菜单, 进行双向绑定