案例 - 图书管理
功能:不离开当前页面,显示单独内容,供用户操作
步骤:
1. 引入 bootstrap.css 和 bootstrap.js
2. 准备弹框标签,确认结构
3. 通过自定义属性,控制弹框的显示和隐藏
1. 通过属性控制,弹框显示或隐藏
<!--
目标:使用Bootstrap弹框
1. 引入bootstrap.css 和 bootstrap.js
2. 准备弹框标签,确认结构
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.js"></script>
2. 通过 JS 控制,弹框显示或隐藏
<script>
// 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').value
console.log('mm', username)
// 2. 隐藏弹框
modal.hide()
})
</script>
步骤:
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:渲染图书列表
* 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()
2. 新增图书(增)
/**
* 目标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 addFrom = document.querySelector('.add-form')
const bookObj = serialize(addFrom, { 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()
// 重置表单
addFrom.reset()
// 隐藏弹框
addModal.hide()
})
addModal.hide()
})
3. 删除图书(删)
/**
* 目标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(自定义属性)
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()
})
}
})
4. 编辑图书(改)
/**
* 目标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')) {
// console.log('编辑')
// 4.2 获取当前图书数据->回显到编辑表单上
const theId = e.target.parentNode.dataset.id
axios({
url: `http://hmajax.itheima.net/api/books/${theId}`
}).then(result => {
// console.log(result)
const bookObj = result.data.data
// document.querySelector('.edit-form .bookname').value = bookObj.bookname
// document.querySelector('.edit-form .author').value = bookObj.author
// document.querySelector('.edit-form .publisher').value = bookObj.publisher
// 数据对象"属性"和标签"类名"一致
// 遍历数据对象,使用属性去获取对应的标签,快速赋值
const keys = Object.keys(bookObj) // ['id', 'bookname', 'author', 'publisher']
// console.log(keys)
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 })
// console.log(bookObj)
// 保存正在编辑的图书id,隐藏起来,无需让用户修改
// <input type="hidden" class="id" name="id" value="238377">
axios({
url: `http://hmajax.itheima.net/api/books/${id}`,
method: 'PUT',
data: {
bookname,
author,
publisher,
creator
}
}).then(() => {
// 修改成功以后,重新获取并刷新列表
getBooksList()
// 隐藏弹框
editModal.hide()
})
editModal.hide()
})
图片上传
1. 获取图片文件对象
2. 使用 FormData 携带图片文件
3. 提交表单数据到服务器,使用图片 url 网址
<script>
/**
* 目标:图片上传,显示到网页上
* 1. 获取图片文件
* 2. 使用 FormData 携带图片文件
* 3. 提交到服务器,获取图片url网址使用
*/
// 文件选择元素->change改变事件
document.querySelector('.upload').addEventListener('change', e => {
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.url
document.querySelector('.my-img').src = imgUrl
})
})
</script>
案例 - 网站换肤
1. 选择图片上传,设置body背景
2. 上传成功时,保存url网址
3. 网页运行后,获取url网址使用
/**
* 目标:网站-更换背景
* 1. 选择图片上传,设置body背景
* 2. 上传成功时,"保存"图片url网址
* 3. 网页运行后,"获取"url网址使用
* */
document.querySelector('.bg-ipt').addEventListener('change', e => {
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 => {
console.log(result)
const imgUrl = result.data.data.url
document.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. 信息渲染
/**
* 目标1:信息渲染
* 1.1 获取用户的数据
* 1.2 回显数据到标签上
* */
const creator = '播仔'
// 1.1 获取用户的数据
axios({
url: 'http://hmajax.itheima.net/api/settings',
params: {
creator
}
}).then(result => {
console.log(result)
const userObj = result.data.data
console.log(userObj)
// 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')
const getNum = userObj[key]
// console.log(getNum)
// 通过性别数字,作为下标,找到对应性别单选框,设置选中状态
gRadioList[getNum].checked = true
}else {
document.querySelector(`.${key}`).value = userObj[key]
}
})
})
2. 头像修改
/**
* 目标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 => {
// console.log(result)
const imgUrl = result.data.data.avatar
// 把新的头像回显到页面
document.querySelector('.prew').src = imgUrl
})
})
3. 提交表单
4. 结果提示
// 保存修改->点击
/**
* 目标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.gender
console.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()
})
})