<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<style>
:root {
font-size: 15px;
}
body {
padding-top: 15px;
}
</style>
</head>
<body >
<!-- 栅格系统 -->
<div class="container">
<div class="d-flex justify-content-between align-items-center">
<h1>图书管理</h1>
<button class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addModal" id="myAddBtn">添加</button>
</div>
<table class="table table-bordered table-striped table-dark table-hover text-center">
<thead>
<!-- 表头行 -->
<tr>
<th scope="col">Id</th>
<th scope="col">书名</th>
<th scope="col">作者</th>
<th scope="col">出版社</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody id="tbody">
<!-- 表格中的每一行 -->
<tr>
<th scope="row">xxx</th>
<td>xxx</td>
<td>xxx</td>
<td>xxx</td>
<td>
<button type="button" class="btn btn-link btn-sm btn-delete">删除</button>
<button type="button" class="btn btn-link btn-sm btn-update">编辑</button>
</td>
</tr>
</tbody>
</table>
</div>
<!-- add Modal -->
<div class="modal fade" id="addModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">添加图书</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="addForm" class="p-3">
<!-- 添加name属性名才能使用 serialize type = 'hidden' 隐藏id属性防止用户修改 -->
<!-- 书名 -->
<div class="mb-3">
<label class="form-label">书名</label>
<input type="text" name="bookname" class="form-control" placeholder="请输入图书名称"
name="bookname" />
</div>
<!-- 作者 -->
<div class="mb-3">
<label class="form-label">作者</label>
<input type="text" name="author" class="form-control" placeholder="请输入作者名字" name="author" />
</div>
<!-- 出版社 -->
<div class="mb-3">
<label class="form-label">出版社</label>
<input type="text" name="publisher" class="form-control" placeholder="请输入出版社名称"
name="publisher" />
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="addBtn">确认</button>
</div>
</div>
</div>
</div>
<!-- edit Modal -->
<div class="modal fade" id="editModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">编辑图书</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="editForm" class="p-3">
<input type="hidden" name="id" />
<!-- 书名 -->
<div class="mb-3">
<label class="form-label">书名</label>
<input type="text" id="bookname" class="form-control" placeholder="请输入图书名称"
name="bookname" />
</div>
<!-- 作者 -->
<div class="mb-3">
<label class="form-label">作者</label>
<input type="text" id="author" class="form-control" placeholder="请输入作者名字" name="author" />
</div>
<!-- 出版社 -->
<div class="mb-3">
<label class="form-label">出版社</label>
<input type="text" id="publisher" class="form-control" placeholder="请输入出版社名称"
name="publisher" />
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="editBtn">确认</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
<script src="./lib/form-serialize.js"></script>
<script>
// 设置axios的基地址 随后所有的请求URL会自动添加基地址
axios.defaults.baseURL = 'http://hmajax.itheima.net'
const addModal = new bootstrap.Modal(document.querySelector('#addModal'))
const editModal = new bootstrap.Modal(document.querySelector('#editModal'))
const addForm = document.querySelector('#addForm')
const editForm = document.querySelector('#editForm')
// 查找数据
function render(){
// axios({
// url:'http://hmajax.itheima.net/api/books',
// params: {
// creater:'刁民'
// }
// })
// 简写 axios 若参数没有直接里面写地址 axios.get('http://hmajax.itheima.net/api/books')
axios.get('http://hmajax.itheima.net/api/books',{params:{creater:'刁民'}}).then(res => {
console.log(res.data.data);
// 打印的是数组定一个变量接收数组
let arr = res.data.data
// 遍历数组
const str = arr.map(item =>{
return `<tr>
<th scope="row">${item.author}</th>
<td>${item.bookname}</td>
<td>${item.creator}</td>
<td>${item.publisher}</td>
<td>
<button data-id ="${item.id}"type="button" class="btn btn-link btn-sm btn-delete">删除</button>
<button data-id ="${item.id}" type="button" class="btn btn-link btn-sm btn-update">编辑</button>
</td>
</tr>
`
}).join('')
document.querySelector('#tbody').innerHTML = str
})
}
render() // 整体思想 把他进行封装函数方便下面调用
//封装delete 函数
function deleteBook(id) {
axios({
// 要写在if判断里面
url:'/api/books/'+id,
method:'DELETE',
})
.then(res =>{
console.log(res);
// 因为删除需要从新渲染结构,所以得调用之前封装好的函数render()
render()
})
}
// 封装编辑函数
function editBook(id) {
//alert(1)
// 显示弹框
editModal.show()
axios({
url:'/api/books/' +id,
method:'GET',
}).then(res =>{
console.log(res.data.data.bookname);
document.querySelector('#bookname').value = res.data.data.bookname
document.querySelector('#author').value = res.data.data.author
editForm.querySelector("[name='id']").value = id
document.querySelector('#publisher').value = res.data.data.publisher
})
}
// 删除数据
// 给tbody注册点击事件 事件委托判断是不是button 按钮 如何查询到当前删除数据 利用自定义属性查找该数据
// 当我点击删除按钮,自动捕捉到该删除行 在button上加个自定义索引号,自定义属性得用引号包裹起来
document.querySelector('#tbody').addEventListener('click',(e) => {
const id = e.target.dataset.id // 索引号
console.log(id);
// 要进行if判断选中的按钮时删除还是编辑 因为俩个按钮都是button
if(e.target.className.includes('btn-delete')) {
deleteBook(id)
} else if (e.target.className.includes('btn-update')){
editBook(id)
}
// 利用axios访问数据
})
// 新增数据
// axios({
// url:'http://hmajax.itheima.net/api/books',
// method: 'POST',
// data: {
// bookname:'鸡太美',
// author:'蔡徐鸡',
// publisher:'小黑社',
// creater:'小黑粉'
// }
// }).then(res => {
// console.log(res.data.data);
// // 打印的是数组定一个变量接收数组
// let arr = res.data.data
// // 遍历数组
// const str = arr.map(item =>{
// return `<tr>
// <th scope="row">${item.author}</th>
// <td>${item.bookname}</td>
// <td>${item.creator}</td>
// <td>${item.publisher}</td>
// <td>
// <button data-index ="${item.id}"type="button" class="btn btn-link btn-sm btn-delete">删除</button>
// <button type="button" class="btn btn-link btn-sm btn-update">编辑</button>
// </td>
// </tr>
// `
// }).join('')
// document.querySelector('#tbody').innerHTML = str
// })
// 3 添加案例 注册点击事件
document.querySelector('#addBtn').addEventListener('click',(e) =>{
const p = serialize(document.querySelector('#addForm'),{hash:true})
axios({
url:'/api/books',
method: 'POST',
data:p // 传输的是对象 根据接口文档
}).then(res => {
console.log(res);
render()// 重新渲染
addModal.hide()
addForm.reset()
})
})
// 保存编辑结果 给按钮注册点击事件
// 获取form表单所有数据 用serialize
document.querySelector('#editBtn').addEventListener('click', (e)=> {
const p = serialize(document.querySelector('#editForm'),{hash : true })
console.log(p);
axios({
url:'/api/books/' +p.id,
method:'PUT',
data:{
bookname:p.bookname,
author:p.author,
publisher:p.publisher
}
}).then(res => {
render()
editModal.hide()
console.log(res);
})
})
</script>
2,原生ajax
<!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>
</head>
<body>
<script>
// 1. new 一个 XMLHttpRequest
const xhr = new XMLHttpRequest()
// 2. 设置请求方式和地址
xhr.open('get', 'http://ajax-api.itheima.net/api/province')
// 3. 发送
xhr.send()
// 4. 监听load事件,取到服务器回来的数据
xhr.addEventListener('load', () => {
console.log(xhr.response) // JSON字符串
console.log(JSON.parse(xhr.response))
})
</script>
</body>
</html>
3.原生ajax带参数查询
<!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>
</head>
<body>
<script>
// 1. new 一个 XMLHttpRequest
const xhr = new XMLHttpRequest()
// 2. 设置请求方式和地址
// xhr.open('get', 'http://ajax-api.itheima.net/api/city?pname=' + encodeURI('湖北省'))
// xhr.open('get', 'http://ajax-api.itheima.net/api/city?pname=湖北省')
xhr.open('get', 'http://ajax-api.itheima.net/api/area?pname=湖北省&cname=武汉市')
// 3. 发送
xhr.send()
// 4. 监听load事件,取到服务器回来的数据
xhr.addEventListener('load', () => {
console.log(xhr.response) // JSON字符串
console.log(JSON.parse(xhr.response))
})
</script>
</body>
</html>
4.原生ajax-post
<!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>
</head>
<body>
<script>
// 1. new XMLHttpRequest
let xhr = new XMLHttpRequest()
// 2. 设置请求方式和url
xhr.open('post', 'http://ajax-api.itheima.net/api/books')
// 根据接口文档的要求,设置请求头content-type
xhr.setRequestHeader('content-type', 'application/json')
// 3. 发送
// send(请求体的内容)
const d = {bookname: '书名', author: '作者', publisher: '出版社'}
xhr.send(JSON.stringify(d))
// 4. 监听load事件,取到服务器回来的数据
xhr.addEventListener('load', () => {
console.log(xhr.response)
})
</script>
</body>
</html>
5.同步异步,回调函数
<script src="https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js"></script>
<script>
console.log(1)
if (true) {
console.log(2);
} else {
console.log(3);
}
setTimeout(() => {
console.log(4);
}, 10)
for (let i = 0; i < 3; i++) {
console.log(6);
}
const fn = () => {
console.log(5);
}
fn()
document.addEventListener('click', () => {
console.log(8);
})
console.log(7);
axios({
url: 'http://ajax-api.itheima.net/api/province',
method: 'GET'
}).then(() => {
console.log(9);
})
console.log(10);
</script>
6.回调函数
<!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>
</head>
<body>
<script>
document.querySelector('').addEventListener('click', ()=>{})
// function fn () {
// console.log(1)
// }
// function t(a){
// a()
// }
// t(fn)
// setTimeout(function(){}, 100)
// setTimeout(fn, 1000)
const arr = [1,2,3]
const fn = (item) => {
console.log(item)
}
arr.forEach(fn) // map, filter, reduce, find, sort ....
</script>
</body>
</html>
7.回调地狱
<!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>
</head>
<body>
<script src="./axios.js"></script>
<script>
// 目标:调用接口,请求第6个省的第1个市下的地区列表
axios.defaults.baseURL = 'http://ajax-api.itheima.net'
axios.get('/api/province').then(res=>{
const pname = res.data.data[5]
console.log(pname)
axios.get('/api/city?pname='+pname).then(res =>{
const cname = res.data.data[0]
console.log(cname)
axios.get(`/api/area?pname=${pname}&cname=${cname}`).then(res => {
console.log(res.data.data)
})
})
})
</script>
</body>
</html>
8.promise基本语法
<script>
// resolve, reject
// 他们是两个函数,作用分别是
// resolve(实参) 执行then,实参会给res
// reject(实参) 执行catch,实参会给err
// finally 一定会执行的
let p1 = new Promise((resolve, reject) => {
// resolve(100)
reject(1)
})
p1.then(res => {
console.log('成功', res)
}).catch(err => {
console.log('失败', err)
}).finally(() => {
console.log('最后一定会执行的')
})
</script>
9.promise三种状态和值
<script>
let p1 = new Promise((resolve, reject) => {
// resolve({a:1}) // [初始]pending ---> [成功]fulfilled ( resolved )
reject(100) // [初始]pending ---> [失败]rejected
})
p1.then(res => {
console.log(res)
}).catch(err =>{
console.log(err)
})
console.log(p1)
</script>
10.promise改写异步回调函数
<script src="./axios.js"></script>
<script>
// const p1 = axios.get('http://ajax-api.itheima.net/api/province')
// axios.get('http://ajax-api.itheima.net/api/province').then().catch
// console.log(p1)
// 1. new 一个 XMLHttpRequest
// const xhr = new XMLHttpRequest()
// // 2. 设置请求方式和地址
// xhr.open('get', 'http://ajax-api.itheima.net/api/province')
// // 3. 发送
// xhr.send()
// // 4. 监听load事件,取到服务器回来的数据
// xhr.addEventListener('load', () => {
// console.log(xhr.response) // JSON字符串
// console.log(JSON.parse(xhr.response))
// })
// function f(){
// const p = new Promise((resolve, reject) => {
// // 写代码
// })
// return p
// }
// f().then().catch()
function myAjax() {
const p = new Promise((resovle, reject) => {
// 1. new 一个 XMLHttpRequest
const xhr = new XMLHttpRequest()
// 2. 设置请求方式和地址
xhr.open('get', 'http://ajax-api.itheima.net/api/province')
// 3. 发送
xhr.send()
// 4. 监听load事件,取到服务器回来的数据
xhr.addEventListener('load', () => {
resovle( JSON.parse(xhr.response) )
// console.log(xhr.response) // JSON字符串
// console.log(JSON.parse(xhr.response))
})
})
return p
}
myAjax()
.then(res => { console.log('ok', res) })
.catch(err => { console.log(err) })
</script>
11.promise面试题
<script>
function sleep(time){
// 请写出你的代码
return new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve()
// }, time)
setTimeout(resolve, time)
})
// const p = new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve()
// }, time)
// })
// return p
}
sleep(2000).then(()=>{
console.log("后续操作")
})
console.log(2);
</script>