Day02_AJAX综合案例 (黑马笔记)

Day02_AJAX综合案例

目录

Day02_AJAX综合案例

学习目标

01.案例_图书管理-介绍

目标

讲解

小结

02.Bootstrap 弹框_属性控制

目标

讲解

小结

03.Bootstrap 弹框_JS控制

目标

讲解

小结

04.案例_图书管理_渲染列表

目标

讲解

小结

05.案例_图书管理_新增图书

目标

讲解

小结

06.案例_图书管理_删除图书

目标

讲解

小结

07-09.案例_图书管理_编辑图书

目标

讲解

小结

10.案例_图书管理_总结

目标

讲解

小结

11.图片上传

目标

讲解

小结

12.案例_网站-更换背景图

目标

讲解

小结

13.案例_个人信息设置-介绍

目标

讲解

小结

14.案例_个人信息设置-信息渲染

目标

讲解

小结

15.案例_个人信息设置-头像修改

目标

讲解

小结

16.案例_个人信息设置-信息修改

目标

讲解

小结

17.案例_个人信息设置-提示框

目标

讲解

小结

今日重点(必须会)

今日作业(必完成)

参考文献


学习目标

今天主要就是练,巩固 axios 的使用

  1. 完成案例-图书管理系统(增删改查)经典业务

  2. 掌握图片上传的思路

  3. 完成案例-网站换肤并实现图片地址缓存

  4. 完成案例-个人信息设置

01.案例_图书管理-介绍

目标

案例-图书管理-介绍(介绍要完成的效果和练习到的思维)

讲解

  1. 打开备课代码运行图书管理案例效果-介绍要完成的增删改查业务效果和 Bootstrap 弹框使用

  2. 分析步骤和对应的视频模块

    • 先学习 Bootstrap 弹框的使用(因为添加图书和编辑图书需要这个窗口来承载图书表单)

    • 先做渲染图书列表(这样做添加和编辑以及删除可以看到数据变化,所以先做渲染)

    • 再做新增图书功能

    • 再做删除图书功能

    • 再做编辑图书功能(注意:编辑和新增图书是2套弹框-后续做项目我们再用同1个弹框)

小结

  1. 做完这个案例我们将会有什么收获呢?

    <details>
    <summary>答案</summary>
    <ul>
    <li>掌握前端经典增删改查的业务和思路,对以后开发很有帮助</li>
    </ul>
    </details>

02.Bootstrap 弹框_属性控制

目标

使用属性方式控制 Bootstarp 弹框的显示和隐藏

讲解

  1. 什么是 Bootstrap 弹框?

    • 不离开当前页面,显示单独内容,供用户操作

  2. 需求:使用 Bootstrap 弹框,先做个简单效果,点击按钮,让弹框出现,点击 X 和 Close 让弹框隐藏

  3. 如何使用 Bootstrap 弹框呢?

    1. 先引入 bootstrap.css 和 bootstrap.js 到自己网页中

    2. 准备弹框标签,确认结构(可以从 Bootstrap 官方文档的 Modal 里复制基础例子)- 运行到网页后,逐一对应标签和弹框每个部分对应关系

    3. 通过自定义属性,通知弹框的显示和隐藏,语法如下:

      <button data-bs-toggle="modal" data-bs-target="css选择器">显示弹框
      </button>
      ​
      <button data-bs-dismiss="modal">Close</button>

  1. 去代码区实现一下

    <!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>Bootstrap 弹框</title><!-- 引入bootstrap.css --><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
    </head>
    ​
    <body><!-- 目标:使用Bootstrap弹框1. 引入bootstrap.css 和 bootstrap.js2. 准备弹框标签,确认结构3. 通过自定义属性,控制弹框的显示和隐藏--><button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target=".my-box">显示弹框</button>
    ​<!-- 弹框标签bootstrap的modal弹框,添加modal类名(默认隐藏)--><div class="modal my-box" tabindex="-1"><div class="modal-dialog"><!-- 弹框-内容 --><div class="modal-content"><!-- 弹框-头部 --><div class="modal-header"><h5 class="modal-title">Modal title</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><!-- 弹框-身体 --><div class="modal-body"><p>Modal body text goes here.</p></div><!-- 弹框-底部 --><div class="modal-footer"><button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button><button type="button" class="btn btn-primary">Save changes</button></div></div></div></div>
    ​<!-- 引入bootstrap.js --><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.min.js"></script>
    </body>
    ​
    </html>

小结

  1. 用哪个属性绑定来控制弹框显示呢?

    <details>
    <summary>答案</summary>
    <ul>
    <li>data-bs-toggle和data-bs-target</li>
    </ul>
    </details>

  2. 用哪个属性来控制隐藏弹框呢?

    <details>
    <summary>答案</summary>
    <ul>
    <li>data-bs-dismiss 关闭的是标签所在的当前提示框</li>
    </ul>
    </details>

03.Bootstrap 弹框_JS控制

目标

使用 JS 方式控制 Bootstarp 弹框的显示和隐藏

讲解

  1. 为什么需要 JS 方式控制呢?

    • 当我显示之前,隐藏之前,需要执行一些 JS 逻辑代码,就需要引入 JS 控制弹框显示/隐藏的方式了

    • 例如:

      • 点击编辑姓名按钮,在弹框显示之前,在输入框填入默认姓名

      • 点击保存按钮,在弹框隐藏之前,获取用户填入的名字并打印

  1. 所以在现实和隐藏之前,需要执行 JS 代码逻辑,就使用 JS 方式 控制 Bootstrap 弹框显示和隐藏

    语法如下:

    // 创建弹框对象
    const modalDom = document.querySelector('css选择器')
    const modal = new bootstrap.Modal(modelDom)
    ​
    // 显示弹框
    modal.show()
    // 隐藏弹框
    modal.hide()

  1. 去代码区实现一下

    // 1. 创建弹框对象
    const modalDom = document.querySelector('.name-box')
    const modal = new bootstrap.Modal(modalDom)
    ​
    // 编辑姓名->点击->赋予默认姓名->弹框显示
    document.querySelector('.edit-btn').addEventListener('click', () => {document.querySelector('.username').value = '默认姓名'
    ​// 2. 显示弹框modal.show()
    })
    ​
    // 保存->点击->->获取姓名打印->弹框隐藏
    document.querySelector('.save-btn').addEventListener('click', () => {const username = document.querySelector('.username').valueconsole.log('模拟把姓名保存到服务器上', username)
    ​// 2. 隐藏弹框modal.hide()
    })

小结

  1. 什么时候用属性控制,什么时候用 JS 控制 Bootstrap 弹框的显示/隐藏?

    <details>
    <summary>答案</summary>
    <ul>
    <li>直接出现/隐藏用属性方式控制,如果需要先执行一段 JS 逻辑再显示/隐藏就用 JS 方式控制</li>
    </ul>
    </details>

04.案例_图书管理_渲染列表

目标

完成图书管理案例-图书列表数据渲染效果

讲解

  1. 需求:基于 axios 获取到图书列表数据,并用 JS 代码渲染数据,到准备好的模板标签中

  2. 步骤:

    1. 获取数据

    2. 渲染数据

  3. 获取数据的时候,需要给自己起一个外号,为什么需要给自己起一个外号呢?

    • 我们所有人数据都来自同一个服务器上,为了区分每个同学不同的数据,需要大家设置一个外号告诉服务器,服务器就会返回你对应的图书数据了

  1. 核心代码如下:

    因为默认展示列表,新增,修改,删除后都要重新获取并刷新列表,所以把获取数据渲染数据的代码封装在一个函数内,方便复用

    /*** 目标1:渲染图书列表*  1.1 获取数据*  1.2 渲染数据*/
    const creator = '老张'
    // 封装-获取并渲染图书列表函数
    function getBooksList() {// 1.1 获取数据axios({url: 'http://hmajax.itheima.net/api/books',params: {// 外号:获取对应数据creator}}).then(result => {// console.log(result)const bookList = result.data.data// console.log(bookList)// 1.2 渲染数据const htmlStr = bookList.map((item, index) => {return `<tr><td>${index + 1}</td><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td data-id=${item.id}><span class="del">删除</span><span class="edit">编辑</span></td></tr>`}).join('')// console.log(htmlStr)document.querySelector('.list').innerHTML = htmlStr})
    }
    // 网页加载运行,获取并渲染列表一次
    getBooksList()

小结

  1. 渲染数据列表的2个步骤是什么?

    <details>
    <summary>答案</summary>
    <ul>
    <li>获取数据,分析结构渲染到页面上</li>
    </ul>
    </details>

05.案例_图书管理_新增图书

目标

完成图书管理案例-新增图书需求

讲解

  1. 需求:点击添加按钮,出现准备好的新增图书弹框,填写图书信息提交到服务器保存,并更新图书列表

  2. 步骤:

    1. 新增弹框(控制显示和隐藏)(基于 Bootstrap 弹框和准备好的表单-用属性和 JS 方式控制)

    2. 在点击保存按钮时,收集数据&提交保存

    3. 刷新-图书列表)(重新调用下之前封装的获取并渲染列表的函数)

  3. 核心代码如下:

    /*** 目标2:新增图书*  2.1 新增弹框->显示和隐藏*  2.2 收集表单数据,并提交到服务器保存*  2.3 刷新图书列表*/
    // 2.1 创建弹框对象
    const addModalDom = document.querySelector('.add-modal')
    const addModal = new bootstrap.Modal(addModalDom)
    // 保存按钮->点击->隐藏弹框
    document.querySelector('.add-btn').addEventListener('click', () => {// 2.2 收集表单数据,并提交到服务器保存const addForm = document.querySelector('.add-form')const bookObj = serialize(addForm, { hash: true, empty: true })// console.log(bookObj)// 提交到服务器axios({url: 'http://hmajax.itheima.net/api/books',method: 'POST',data: {...bookObj,creator}}).then(result => {// console.log(result)// 2.3 添加成功后,重新请求并渲染图书列表getBooksList()// 重置表单addForm.reset()// 隐藏弹框addModal.hide()})
    })

小结

  1. 新增数据的3个步骤是什么?

    <details>
    <summary>答案</summary>
    <ul>
    <li>准备好数据标签和样式,然后收集表单数据提交保存,刷新列表</li>
    </ul>
    </details>

06.案例_图书管理_删除图书

目标

完成图书管理案例-删除图书需求

讲解

  1. 需求:点击图书删除元素,删除当前图书数据

  2. 步骤:

    1. 给删除元素,绑定点击事件(事件委托方式并判断点击的是删除元素才走删除逻辑代码),并获取到要删除的数据id

    2. 基于 axios 和接口文档,调用删除接口,让服务器删除这条数据

    3. 重新获取并刷新图书列表

  1. 核心代码如下:

    /*** 目标3:删除图书*  3.1 删除元素绑定点击事件->获取图书id*  3.2 调用删除接口*  3.3 刷新图书列表*/
    // 3.1 删除元素->点击(事件委托)
    document.querySelector('.list').addEventListener('click', e => {// 获取触发事件目标元素// console.log(e.target)// 判断点击的是删除元素if (e.target.classList.contains('del')) {// console.log('点击删除元素')// 获取图书id(自定义属性id)const theId = e.target.parentNode.dataset.id// console.log(theId)// 3.2 调用删除接口axios({url: `http://hmajax.itheima.net/api/books/${theId}`,method: 'DELETE'}).then(() => {// 3.3 刷新图书列表getBooksList()})}
    })

小结

  1. 删除数据的步骤是什么?

    <details>
    <summary>答案</summary>
    <ul>
    <li>告知服务器要删除的数据id,服务器删除后,重新获取并刷新列表</li>
    </ul>
    </details>

07-09.案例_图书管理_编辑图书

目标

完成图书管理案例-编辑图书需求

讲解

  1. 因为编辑图书要做回显等,比较复杂,所以分了3个视频来讲解

  2. 需求:完成编辑图书回显当前图书数据到编辑表单,在用户点击修改按钮,收集数据提交到服务器保存,并刷新列表

  3. 编辑数据的核心思路:

    1. 给编辑元素,绑定点击事件(事件委托方式并判断点击的是编辑元素才走编辑逻辑代码),并获取到要编辑的数据id

    2. 基于 axios 和接口文档,调用查询图书详情接口,获取正在编辑的图书数据,并回显到表单中(页面上的数据是在用户的浏览器中不够准备,所以只要是查看数据都要从服务器获取)

    3. 收集并提交保存修改数据,并重新从服务器获取列表刷新页面

  1. 核心代码如下:

    /*** 目标4:编辑图书*  4.1 编辑弹框->显示和隐藏*  4.2 获取当前编辑图书数据->回显到编辑表单中*  4.3 提交保存修改,并刷新列表*/
    // 4.1 编辑弹框->显示和隐藏
    const editDom = document.querySelector('.edit-modal')
    const editModal = new bootstrap.Modal(editDom)
    // 编辑元素->点击->弹框显示
    document.querySelector('.list').addEventListener('click', e => {// 判断点击的是否为编辑元素if (e.target.classList.contains('edit')) {// 4.2 获取当前编辑图书数据->回显到编辑表单中const theId = e.target.parentNode.dataset.idaxios({url: `http://hmajax.itheima.net/api/books/${theId}`}).then(result => {const bookObj = result.data.data// document.querySelector('.edit-form .bookname').value = bookObj.bookname// document.querySelector('.edit-form .author').value = bookObj.author// 数据对象“属性”和标签“类名”一致// 遍历数据对象,使用属性去获取对应的标签,快速赋值const keys = Object.keys(bookObj) // ['id', 'bookname', 'author', 'publisher']keys.forEach(key => {document.querySelector(`.edit-form .${key}`).value = bookObj[key]})})editModal.show()}
    })
    // 修改按钮->点击->隐藏弹框
    document.querySelector('.edit-btn').addEventListener('click', () => {// 4.3 提交保存修改,并刷新列表const editForm = document.querySelector('.edit-form')const { id, bookname, author, publisher } = serialize(editForm, { hash: true, empty: true})// 保存正在编辑的图书id,隐藏起来:无需让用户修改// <input type="hidden" class="id" name="id" value="84783">axios({url: `http://hmajax.itheima.net/api/books/${id}`,method: 'PUT',data: {bookname,author,publisher,creator}}).then(() => {// 修改成功以后,重新获取并刷新列表getBooksList()
    ​// 隐藏弹框editModal.hide()})
    })

小结

  1. 编辑数据的步骤是什么?

    <details>
    <summary>答案</summary>
    <ul>
    <li>获取正在编辑数据并回显,收集编辑表单的数据提交保存,重新获取并刷新列表</li>
    </ul>
    </details>

10.案例_图书管理_总结

目标

总结下增删改查的核心思路

讲解

  1. 因为增删改查的业务在前端实际开发中非常常见,思路是可以通用的,所以总结下思路

    1.渲染列表(查)

    2.新增图书(增)

    3.删除图书(删)

    4.编辑图书(改)

  2. 渲染数据(查)

    核心思路:获取数据 -> 渲染数据

    // 1.1 获取数据
    axios({...}).then(result => {const bookList = result.data.data// 1.2 渲染数据const htmlStr = bookList.map((item, index) => {return `<tr><td>${index + 1}</td><td>${item.bookname}</td><td>${item.author}</td><td>${item.publisher}</td><td data-id=${item.id}><span class="del">删除</span><span class="edit">编辑</span></td></tr>`}).join('')document.querySelector('.list').innerHTML = htmlStr
    })

  1. 新增数据(增)

    核心思路:准备页面标签 -> 收集数据提交(必须) -> 刷新页面列表(可选)

    // 2.1 创建弹框对象
    const addModalDom = document.querySelector('.add-modal')
    const addModal = new bootstrap.Modal(addModalDom)
    document.querySelector('.add-btn').addEventListener('click', () => {// 2.2 收集表单数据,并提交到服务器保存const addForm = document.querySelector('.add-form')const bookObj = serialize(addForm, { hash: true, empty: true })axios({...}).then(result => {// 2.3 添加成功后,重新请求并渲染图书列表getBooksList()addForm.reset()addModal.hide()})
    })

  1. 删除图书(删)

    核心思路:绑定点击事件(获取要删除的图书唯一标识) -> 调用删除接口(让服务器删除此数据) -> 成功后重新获取并刷新列表

    // 3.1 删除元素->点击(事件委托)
    document.querySelector('.list').addEventListener('click', e => {if (e.target.classList.contains('del')) {// 获取图书id(自定义属性id)const theId = e.target.parentNode.dataset.id// 3.2 调用删除接口axios({...}).then(() => {// 3.3 刷新图书列表getBooksList()})}
    })
  2. 编辑图书(改)

    核心思路:准备编辑图书表单 -> 表单回显正在编辑的数据 -> 点击修改收集数据 -> 提交到服务器保存 -> 重新获取并刷新列表

    // 4.1 编辑弹框->显示和隐藏
    const editDom = document.querySelector('.edit-modal')
    const editModal = new bootstrap.Modal(editDom)
    document.querySelector('.list').addEventListener('click', e => {if (e.target.classList.contains('edit')) {// 4.2 获取当前编辑图书数据->回显到编辑表单中const theId = e.target.parentNode.dataset.idaxios({...}).then(result => {const bookObj = result.data.data// 遍历数据对象,使用属性去获取对应的标签,快速赋值const keys = Object.keys(bookObj) keys.forEach(key => {document.querySelector(`.edit-form .${key}`).value = bookObj[key]})})editModal.show()}
    })
    ​
    document.querySelector('.edit-btn').addEventListener('click', () => {// 4.3 提交保存修改,并刷新列表const editForm = document.querySelector('.edit-form')const { id, bookname, author, publisher } = serialize(editForm, { hash: true, empty: true})// 保存正在编辑的图书id,隐藏起来:无需让用户修改// <input type="hidden" class="id" name="id" value="84783">axios({...}).then(() => {getBooksList()editModal.hide()})
    })

小结

  1. 学完图书管理案例,我们收货了什么?

    <details>
    <summary>答案</summary><ul>
    <li>现在编辑的虽然是图书数据,以后编辑其他数据,再做增删改查都是差不多的思路</li>
    </ul>
    </details>

11.图片上传

目标

把本地图片上传到网页上显示

讲解

  1. 什么是图片上传?

    • 就是把本地的图片上传到网页上显示

  2. 图片上传怎么做?

    • 先依靠文件选择元素获取用户选择的本地文件,接着提交到服务器保存,服务器会返回图片的 url 网址,然后把网址加载到 img 标签的 src 属性中即可显示

  3. 为什么不直接显示到浏览器上,要放到服务器上呢?

    • 因为浏览器保存是临时的,如果你想随时随地访问图片,需要上传到服务器上

  4. 图片上传怎么做呢?

    1. 先获取图片文件对象

    2. 使用 FormData 表单数据对象装入(因为图片是文件而不是以前的数字和字符串了所以传递文件一般需要放入 FormData 以键值对-文件流的数据传递(可以查看请求体-确认请求体结构)

      const fd = new FormData()
      fd.append(参数名, 值)

    3. 提交表单数据对象,使用服务器返回图片 url 网址

  5. 核心代码如下:

    <!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>图片上传</title>
    </head>
    ​
    <body><!-- 文件选择元素 --><input type="file" class="upload"><img src="" alt="" class="my-img">
    ​<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>/*** 目标:图片上传,显示到网页上*  1. 获取图片文件*  2. 使用 FormData 携带图片文件*  3. 提交到服务器,获取图片url网址使用*/// 文件选择元素->change改变事件document.querySelector('.upload').addEventListener('change', e => {// 1. 获取图片文件console.log(e.target.files[0])// 2. 使用 FormData 携带图片文件const fd = new FormData()fd.append('img', e.target.files[0])// 3. 提交到服务器,获取图片url网址使用axios({url: 'http://hmajax.itheima.net/api/uploadimg',method: 'POST',data: fd}).then(result => {console.log(result)// 取出图片url网址,用img标签加载显示const imgUrl = result.data.data.urldocument.querySelector('.my-img').src = imgUrl})})</script>
    </body>
    ​
    </html>

小结

  1. 图片上传的思路是什么?

    <details>
    <summary>答案</summary>
    <ul>
    <li>先用文件选择元素,获取到文件对象,然后装入 FormData 表单对象中,再发给服务器,得到图片在服务器的 URL 网址,再通过 img 标签加载图片显示</li>
    </ul>
    </details>

12.案例_网站-更换背景图

目标

实现更换网站背景图的效果

讲解

  1. 需求:先运行备课代码,查看要完成的效果,点击右上角选择本机中提供的素材图片,更换网站背景图

  2. 网站更换背景图如何实现呢,并且保证刷新后背景图还在?具体步骤:

    1. 先获取到用户选择的背景图片,上传并把服务器返回的图片 url 网址设置给 body 背景

    2. 上传成功时,保存图片 url 网址到 localStorage 中

    3. 网页运行后,获取 localStorage 中的图片的 url 网址使用(并判断本地有图片 url 网址字符串才设置)

  3. 核心代码如下:

    /*** 目标:网站-更换背景*  1. 选择图片上传,设置body背景*  2. 上传成功时,"保存"图片url网址*  3. 网页运行后,"获取"url网址使用* */
    document.querySelector('.bg-ipt').addEventListener('change', e => {// 1. 选择图片上传,设置body背景console.log(e.target.files[0])const fd = new FormData()fd.append('img', e.target.files[0])axios({url: 'http://hmajax.itheima.net/api/uploadimg',method: 'POST',data: fd}).then(result => {const imgUrl = result.data.data.urldocument.body.style.backgroundImage = `url(${imgUrl})`
    ​// 2. 上传成功时,"保存"图片url网址localStorage.setItem('bgImg', imgUrl)})
    })
    ​
    // 3. 网页运行后,"获取"url网址使用
    const bgUrl = localStorage.getItem('bgImg')
    console.log(bgUrl)
    bgUrl && (document.body.style.backgroundImage = `url(${bgUrl})`)

小结

  1. localStorage 取值和赋值的语法分别是什么?

    <details>
    <summary>答案</summary>
    <ul>
    <li>localStorage.getItem('key')是取值,localStorage.setItem('key', 'value')是赋值</li>
    </ul>
    </details>

13.案例_个人信息设置-介绍

目标

介绍个人信息设置案例-需要完成哪些效果,分几个视频讲解

讲解

  1. 需求:先运行备课代码,查看要完成的效果

  2. 本视频分为,信息回显 + 头像修改 + 信息修改+ 提示框反馈 4 部分

    1. 先完成信息回显

    2. 再做头像修改-立刻就更新给此用户

    3. 收集个人信息表单-提交保存

    4. 提交后反馈结果给用户(提示框)

小结

暂无

14.案例_个人信息设置-信息渲染

目标

把外号对应的用户信息渲染到页面上

讲解

  1. 需求:把外号对应的个人信息和头像,渲染到页面表单和头像标签上。

  2. 注意:还是需要准备一个外号,因为想要查看自己对应的用户信息,不想被别人影响

  3. 步骤:

    • 获取数据

    • 渲染数据到页面

  4. 代码如下:

    /*** 目标1:信息渲染*  1.1 获取用户的数据*  1.2 回显数据到标签上* */
    const creator = '播仔'
    // 1.1 获取用户的数据
    axios({url: 'http://hmajax.itheima.net/api/settings',params: {creator}
    }).then(result => {const userObj = result.data.data// 1.2 回显数据到标签上Object.keys(userObj).forEach(key => {if (key === 'avatar') {// 赋予默认头像document.querySelector('.prew').src = userObj[key]} else if (key === 'gender') {// 赋予默认性别// 获取性别单选框:[男radio元素,女radio元素]const gRadioList = document.querySelectorAll('.gender')// 获取性别数字:0男,1女const gNum = userObj[key]// 通过性别数字,作为下标,找到对应性别单选框,设置选中状态gRadioList[gNum].checked = true} else {// 赋予默认内容document.querySelector(`.${key}`).value = userObj[key]}})
    })

小结

  1. 渲染数据和图书列表的渲染思路是否一样呢,是什么?

    <details>
    <summary>答案</summary>
    <ul>
    <li>一样的,都是获取到数据,然后渲染到页面上</li>
    </ul>
    </details>

15.案例_个人信息设置-头像修改

目标

修改用户的头像并立刻生效

讲解

  1. 需求:点击修改用户头像

  2. 实现步骤如下:

    1. 获取到用户选择的头像文件

    2. 调用头像修改接口,并除了头像文件外,还要在 FormData 表单数据对象中携带外号

    3. 提交到服务器保存此用户对应头像文件,并把返回的头像图片 url 网址设置在页面上

  3. 注意:重新刷新重新获取,已经是修改后的头像了(证明服务器那边确实保存成功)

  4. 核心代码:

    /*** 目标2:修改头像*  2.1 获取头像文件*  2.2 提交服务器并更新头像* */
    // 文件选择元素->change事件
    document.querySelector('.upload').addEventListener('change', e => {// 2.1 获取头像文件console.log(e.target.files[0])const fd = new FormData()fd.append('avatar', e.target.files[0])fd.append('creator', creator)// 2.2 提交服务器并更新头像axios({url: 'http://hmajax.itheima.net/api/avatar',method: 'PUT',data: fd}).then(result => {const imgUrl = result.data.data.avatar// 把新的头像回显到页面上document.querySelector('.prew').src = imgUrl})
    })

小结

  1. 为什么这次上传头像,需要携带外号呢?

    <details>
    <summary>答案</summary>
    <ul>
    <li>因为这次头像到后端,是要保存在某个用户名下的,所以要把外号名字一起携带过去</li>
    </ul>
    </details>

16.案例_个人信息设置-信息修改

目标

把用户修改的信息提交到服务器保存

讲解

  1. 需求:点击提交按钮,收集个人信息,提交到服务器保存(无需重新获取刷新,因为页面已经是最新的数据了)

    1. 收集表单数据

    2. 提交到服务器保存-调用用户信息更新接口(注意请求方法是 PUT)代表数据更新的意思

  2. 核心代码如下:

    /*** 目标3:提交表单*  3.1 收集表单信息*  3.2 提交到服务器保存*/
    // 保存修改->点击
    document.querySelector('.submit').addEventListener('click', () => {// 3.1 收集表单信息const userForm = document.querySelector('.user-form')const userObj = serialize(userForm, { hash: true, empty: true })userObj.creator = creator// 性别数字字符串,转成数字类型userObj.gender = +userObj.genderconsole.log(userObj)// 3.2 提交到服务器保存axios({url: 'http://hmajax.itheima.net/api/settings',method: 'PUT',data: userObj}).then(result => {})
    })

小结

  1. 信息修改数据和以前增删改查哪个实现的思路比较接近呢?

    <details>
    <summary>答案</summary>
    <ul>
    <li>编辑,首先回显已经做完了,然后收集用户最新改动后的数据,提交到服务器保存,因为页面最终就是用户刚写的数据,所以不用重新获取并刷新页面了</li>
    </ul>
    </details>

17.案例_个人信息设置-提示框

目标

把用户更新个人信息结果,用提示框反馈给用户

讲解

  1. 需求:使用 bootstrap 提示框,提示个人信息设置后的结果

  2. bootstrap 的 toast 提示框和 modal 弹框使用很像,语法如下:

    1. 先准备对应的标签结构(模板里已有)

    2. 设置延迟自动消失的时间

      <div class="toast" data-bs-delay="1500">提示框内容
      </div>

    3. 使用 JS 的方式,在 axios 请求响应成功时,展示结果

      // 创建提示框对象
      const toastDom = document.querySelector('css选择器')
      const toast = new bootstrap.Toast(toastDom)
      ​
      // 显示提示框
      toast.show()

  1. 核心代码:

    /*** 目标3:提交表单*  3.1 收集表单信息*  3.2 提交到服务器保存*/
    /*** 目标4:结果提示*  4.1 创建toast对象*  4.2 调用show方法->显示提示框*/
    // 保存修改->点击
    document.querySelector('.submit').addEventListener('click', () => {// 3.1 收集表单信息const userForm = document.querySelector('.user-form')const userObj = serialize(userForm, { hash: true, empty: true })userObj.creator = creator// 性别数字字符串,转成数字类型userObj.gender = +userObj.genderconsole.log(userObj)// 3.2 提交到服务器保存axios({url: 'http://hmajax.itheima.net/api/settings',method: 'PUT',data: userObj}).then(result => {// 4.1 创建toast对象const toastDom = document.querySelector('.my-toast')const toast = new bootstrap.Toast(toastDom)
    ​// 4.2 调用show方法->显示提示框toast.show()})
    })

小结

  1. bootstrap 弹框什么时候用 JS 方式控制显示呢?

    <details>
    <summary>答案</summary>
    <ul>
    <li>需要执行一些其他的 JS 逻辑后,再去显示/隐藏弹框时</li>
    </ul>
    </details>

今日重点(必须会)

  1. 掌握增删改查数据的思路

  2. 掌握图片上传的思路和流程

  3. 理解调用接口时,携带外号的作用

  4. 了解 bootstrap 弹框的使用

今日作业(必完成)

在配套作业文件夹的md内

参考文献

  1. 表单概念->百度百科

  2. accept属性->mdn

  3. accept属性->菜鸟教程

  4. FormData->mdn

  5. BS的Model文档

  6. axios请求方式别名

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/19053.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

六、代码生成,《编译原理》(本科教学版),第2版

文章目录 零、前言0.1 编译器前端到后端 一、代码生成1.1 代码生成的任务1.2 给数据分配计算资源1.3 给代码选择合适的机器指令1.4 栈式计算机1.4.1 栈式计算机Stack的结构1.4.2 栈计算机的指令集1.4.3 变量的内存分配伪指令1.4.4 栈式计算机的代码生成1.4.4.1 递归下降代码生成…

Android集成FCM(Firebace Cloud Messaging )

集成FCM官方文档 Firebace主页面 将 Firebase 添加到您的 Android 应用 1、进入Firebace页面&#xff0c;创建自己的项目 2、点击自己创建好的项目&#xff0c;在右侧选择Cloud Messaging 3、点击Android去创建 google-services.json 4、将下载的 google-services.json 文件…

D2076——一款双通道音频功率放大器【青牛科技】

概述&#xff1a; D2076是一款双通道音频功率放大器&#xff0c;最低工作电压可到1.0V。适用于 便携式小型收音机或立体声耳机作双通道或BTL应用。 主要特点&#xff1a; BTL工作&#xff0c;Po90mW&#xff08;典型值&#xff09; 外接元器件少 通过外接PNP三极管作为…

智慧社区平台系统提升物业管理效率与居民生活质量

内容概要 智慧社区平台系统是为应对现代城市管理挑战而诞生的重要工具。随着城市化进程的加快&#xff0c;传统的物业管理方式已经难以满足日益增长的居民需求和管理复杂性。因此&#xff0c;引入智能化管理手段显得尤为重要。这个系统不仅仅是一个简单的软件&#xff0c;它是…

【langchain4j】AIservices能够实现更加灵活的chain

文章目录 AI service介绍如何工作的AiServices提供的能力支持的返回形式 简单的例子&#xff1a;接收用户消息&#xff0c;并按规定返回接收单个变量接收更多动态变量 advanced RAGChaining multiple AI Services&#xff1a;多个AiSerives合并到一起相关教程&#xff1a;[Lang…

JavaScript 中字符串和数组的概念解析与多角度对比区分

文章目录 &#x1f4af;前言&#x1f4af;字符串&#xff08;String&#xff09;&#x1f4af;数组&#xff08;Array&#xff09;&#x1f4af;字符串与数组的相同点与不同点&#x1f4af;字符串和数组的实际应用场景&#x1f4af;字符串与数组的互转&#x1f4af;字符串和数组…

4K双模MiniLED显示器哪个好

4K双模MiniLED显示器哪个好&#xff1f;现在市面上的4K双模MiniLED显示器太多了&#xff0c;琳琅满目&#xff0c;今天就给大家列举一下7款当下火热到爆炸的品牌&#xff0c;看看4K双模MiniLED显示器哪个好。 4K双模MiniLED显示器哪个好 - HKC G27M7PRO HKC G27M7Pro 是一款性…

每天五分钟深度学习pytorch:批归一化全连接网络完成手写字体识别

本文重点 前面我们学习了普通的全连接神经网络,后面我们学习了带有激活层的全连接神经网络,本文我们继续进一步升级,我们学习带有批归一化的全连接神经网络,批归一化可以加快神经网络的训练速度,减少过拟合,具体它的原理,大家可以看我们的《每天五分钟深度学习》专栏,…

excel打开csv文件乱码的问题

如图所示&#xff0c;在保存csv文件时已指定编码为utf-8&#xff0c;用excel打开后仍然乱码 解决方法&#xff1a; 在保存csv文件时指定编码为utf-8-sig 该编码方式会在文件开头加入一个 BOM&#xff08;Byte Order Mark&#xff09;&#xff0c;有助于 Excel 正确识别 UTF-8…

QQ音乐 11.3.4 | 魅族定制版,极致简洁,无广告,不限机型

QQ音乐魅族定制版&#xff0c;界面设计极致简洁&#xff0c;没有任何广告干扰&#xff0c;支持听限免歌曲&#xff0c;不限机型使用。用户可以通过微信和QQ直接登录&#xff0c;享受纯净的音乐体验。 大小&#xff1a;94.6M 下载地址&#xff1a; 百度网盘&#xff1a;https:…

使用TensorFlow实现简化版 GoogLeNet 模型进行 MNIST 图像分类

在本文中&#xff0c;我们将使用 TensorFlow 和 Keras 实现一个简化版的 GoogLeNet 模型来进行 MNIST 数据集的手写数字分类任务。GoogLeNet 采用了 Inception 模块&#xff0c;这使得它在处理图像数据时能更高效地提取特征。本教程将详细介绍如何在 MNIST 数据集上训练和测试这…

TON商城与Telegram App:生态融合与去中心化未来的精彩碰撞

随着区块链技术的快速发展&#xff0c;去中心化应用&#xff08;DApp&#xff09;逐渐成为了数字生态的重要组成部分。而Telegram作为全球领先的即时通讯应用&#xff0c;不仅仅满足于传统的社交功能&#xff0c;更在区块链领域大胆探索&#xff0c;推出了基于其去中心化网络的…

vulhub之log4j

Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645) 漏洞简介 Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码。 Apache Log4j 在应用程序中添加日志记录最…

web服务nginx实验4:访问控制

4-1&#xff1a;基于不同用户的访问控制&#xff1a; 安装软件&#xff1a; 创建HTTP基本认证用户密码文件&#xff0c;tom&#xff0c;密码&#xff1a;1&#xff0c;lisa&#xff0c;密码&#xff1a;1&#xff1a; -c&#xff1a;表示创建一个新的密码文件。如果该文件已经…

基于FastAPI实现本地大模型API封装调用

关于FastAPI FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Python Web 框架&#xff0c;用于构建基于标准 Python 类型提示的 API。它以简洁、直观和高效的方式提供工具&#xff0c;特别适合开发现代 web 服务和后端应用程序。 问题&#xff1a;_pad() got an un…

数字化点亮库布其沙漠的绿色梦想

Bentley 应用程序助力提升设计和施工效率&#xff0c;提前六周交付设计成果 清洁能源为沙漠带来新活力 库布其光伏治沙项目&#xff08;以下简称“该项目”&#xff09;位于内蒙古鄂尔多斯市库布其沙漠&#xff0c;占地约 10 万亩&#xff0c;是中国单体规模最大的光伏治沙项目…

基于单片机的风能太阳能供电的路灯智能控制系统设计(论文+源码)

1系统总体设计 本课题为风能太阳能供电的路灯智能控制系统设计&#xff0c;系统的主要功能设计如下&#xff1a; &#xff08;1&#xff09; 供电模块&#xff1a;采用太阳能板以及风机模拟风扇充电&#xff0c;经过充电电路给锂电池进行充电。再由锂电池给照明模块以及整个项…

Linux Centos7 Rocky网卡配置

目录 1.Vmare 虚拟机配置 &#xff08;1&#xff09;打开虚拟机输入ip a&#xff0c;查看ip网段&#xff0c;若为192.168.81.135 &#xff08;2&#xff09;在Vmare上的虚拟网络配置器配置 &#xff08;3&#xff09;确保电脑有VMnet1 VMnet8 2.Linux虚拟机Centos配置 &#…

MySQL索引原理之查询优化

MySQL索引原理之查询优化 1、慢查询定位 开启慢查询日志 查看 MySQL 数据库是否开启了慢查询日志和慢查询日志文件的存储位置的命令如下&#xff1a; SHOW VARIABLES LIKE %slow_query_log%通过如下命令开启慢查询日志&#xff1a; SET global slow_query_log 1; SET global …

ArchGuard 架构分析器发布:多语言、跨项目架构数据生成,助力 AI 时代知识挖掘...

TL;DR&#xff1a;https://github.com/archguard/archguard 过去的几个月里&#xff0c;我们一直在探索用 AI 辅助跨项目、跨大量微服务的系统的开发。其中一个重要的话题就是&#xff0c;从现有的软件架构去生成知识&#xff0c;文档是落后、多版本的&#xff0c; 只有代码才保…