文章目录
前言
在前端开发中,最频繁的操作几乎就是对数据的增删改查,在如今React,Vue,Angular等框架的盛行,但对原生dom的操作也需要熟练掌握,本文就对操作原生dom实现图书管理系统,利用axios与后端数据进行交互(这里利用的是黑马网站的公共交互接口),效果呈现如下:
一、准备工作
1.创建文件
首先在vscode里安装live server这个插件,它可以帮助我们在浏览器快速打开我们的html项目的网页方便视察,然后在工作区创建一个html文件,在新文件输入html5按下回车即可快速创建一个模板
2.导入依赖
项目使用了form-serialize实现对表单数据的一步整体获取,form-serialize需要自行下载导入(下载地址) ,以及axios库与后端进行交互,所以需要通过script标签对相关依赖进行引入,代码如下
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.min.js"></script>
<script src="./lib/form-serialize.js"></script>
3.html视图准备
视图准备了一个table表格和两个form表单,在tbody处是数据展示的地方,后面会使用javascript进行渲染,两个form表单一开始是处于不显示的状态,后续添加事件进行更改
<body>
<div class="data">
<div class="butt">
<button class="add">添加</button>
</div>
<table>
<thead>
<tr>
<th>序号</th>
<th>书名</th>
<th>作者</th>
<th>出版社</th>
<th>操作</th>
</tr>
</thead>
<tbody class="list">
</tbody>
</table>
</div>
<div class="fom1">
<form class="xzts">
<span>新增图书</span>
<div class="bookName"><span>书名</span><input type="text" name="bookname" /></div>
<div class="auThor"><span>作者</span><input type="text" name="author" /></div>
<div class="puBlisher"><span>出版社</span><input type="text" name="publisher" /></div>
<div class="confirm">
<button class="yes1">确认</button>
<button class="no1">取消</button>
</div>
</form>
</div>
<div class="fom2">
<form class="bjts">
<input type="hidden" class="id" name="id">
<span>编辑图书</span>
<div class="bookName"><span>书名</span><input type="text" name="bookname" class="bookname" /></div>
<div class="auThor"><span>作者</span><input type="text" name="author" class="author" /></div>
<div class="puBlisher"><span>出版社</span><input type="text" name="publisher" class="publisher" /></div>
<div class="confirm">
<button class="yes2">确认</button>
<button class="no2">取消</button>
</div>
</form>
</div>
</body>
样式的css代码如下,可以根据自己需求更改
<style>
body {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.data {
display: flex;
flex-direction: column;
}
span {
font-size: bold;
}
.sp1 {
color: rgb(0, 149, 255);
}
.sp2 {
color: rgb(255, 56, 56);
}
.add {
float: right;
color: aliceblue;
border: 1 px;
border-radius: 4px;
border-style: none;
margin-bottom: 10px;
padding: 5px 10px;
background-color: rgb(41, 157, 215);
}
table {
border-collapse: collapse;
border: 2px solid rgb(140 140 140);
font-family: sans-serif;
font-size: 0.8rem;
letter-spacing: 1px;
}
thead {
color: rgb(255, 255, 255);
background-color: rgba(198, 202, 197, 0.958);
}
th,
td {
border: 1px solid rgb(160 160 160);
padding: 8px 10px;
text-align: center;
}
.fom1,
.fom2 {
width: 100%;
height: 100%;
display: none;
position: absolute;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.5);
z-index: 9999;
}
form {
border: 1px solid #ccc;
border-radius: 4px;
width: 300px;
height: 250px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
form div {
margin-bottom: 10px;
margin-top: 10px;
}
.bookName,
.auThor,
.puBlish {
display: flex;
align-items: center;
justify-content: center;
}
form span {
margin-right: 10px;
}
input {
padding: 5px;
border: 1px solid #ccc;
border-radius: 5px;
}
input:focus {
outline: none;
border-color: #007bff;
}
.confirm {
display: flex;
}
.confirm button {
margin-left: 45px;
margin-right: 45px;
color: aliceblue;
padding: 5px 10px;
border-radius: 4px;
border-style: none;
background-color: rgb(41, 157, 215);
}
</style>
二、图书管理系统的渲染
1.封装getBookList()函数
这里定义一个变量,设置需要获取的指定对象的数据,然后调用axios的GET方法,获取后端接口中老周的数据,然后根据返回结果利用map方法对表格进行数据的渲染,将返回的html字符串通过innerHTML插入到选择器选择的元素中,如果遇到错误在控制台输出错误
const creator = '老周';
function getBookList() {
axios.get('http://hmajax.itheima.net/api/books', {
params: {
creator: creator
}
}).then(res => {
const data = res.data.data;
const str = data.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="sp1">编辑</span>
<span class="sp2">删除</span>
</td>
</tr>
`;
}).join('');//转字符串
document.querySelector('.list').innerHTML = str;
}).catch(error => {
console.log(error);
});
}
2.在代码底部执行封装过的函数进行渲染
getBookList();
三、图书管理系统的添加
1.封装addBook()函数
该函数使用了serialize对表单输入框所有元素的获取,addForm 的表单元素中的值序列化为一个对象。{ hash: true, empty: false } 是一个选项对象,用于指定序列化的方式。其中,hash: true 表示将表单元素的 name 属性作为对象的键,empty: false 表示不包含空值的表单元素。然后通过axios的POST方法将获取的的数据提交给后端接口,在控制台输出返回结果和错误结果,并且重新执行一次渲染函数将最新数据及时更新,提交表单之后将表单置为隐藏
function addBook() {
const addForm = document.querySelector('.xzts');
const bookadd = serialize(addForm, { hash: true, empty: false });
axios.post('http://hmajax.itheima.net/api/books', {
...bookadd,
creator
}).then(res => {
console.log(res);
getBookList();
}).catch(error => {
console.log(error);
});
document.querySelector('.fom1').style.display = 'none';
}
2.添加按钮绑定事件
点击添加按钮时,添加的表单显示出来,并且给表单中的确定选项添加监听事件,首先阻止表单的默认提交,再调用addBook()函数的方法进行添加数据,取消选项绑定监听事件用于隐藏表单
document.querySelector('.add').addEventListener('click', () => {
document.querySelector('.fom1').style.display = 'flex';
});
document.querySelector('.yes1').addEventListener('click', event => {
event.preventDefault();
addBook();
});
document.querySelector('.no1').addEventListener('click', event => {
event.preventDefault();
document.querySelector('.fom1').style.display = 'none';
});
四、图书管理系统的删除
1.封装 deleteBook()函数
函数中传递参数指定删除的id,调用axios里的DELETE方法对数据进行删除并重新渲染
function deleteBook(id) {
axios.delete(`http://hmajax.itheima.net/api/books/${id}`).then(res => {
console.log(res);
getBookList();
}).catch(error => {
console.log(error);
});
}
2.绑定事件
因为删除和编辑按钮是后来动态生成的,原来dom上没有该元素,所以需要找到原来存在的父元素对监听事件进行事件委托,获取当前点击的元素是否与需要的相同,然后执行删除方法
document.querySelector('.list').addEventListener('click', e => {
if (e.target.classList.contains('sp2')) {
const id = e.target.parentNode.dataset.id;
deleteBook(id);
}
});
五、图书管理系统的编辑
1.封装editBook()函数
该函数用于回显原来的数据在表单输入框上,通过axios的GET方法获取到当前点击的id数据,利用Object.keys方法获取数据的key值,再根据key值对对应的表单输入框进行数据的渲染
function editBook(id) {
axios.get(`http://hmajax.itheima.net/api/books/${id}`).then(res => {
const bookObj = res.data.data;
const key = Object.keys(bookObj);
key.forEach(key => {
document.querySelector(`.bjts .${key}`).value = bookObj[key];
});
});
document.querySelector('.fom2').style.display = 'flex';
}
2.封装updateBook()函数
解构出通过serialize获取的编辑好的输入框的内容,然后使用axios的PUT方法对数据进行提交更改,包括当前修改的对象id,用于指定修改的是谁
function updateBook() {
const editForm = document.querySelector('.bjts');
const { id, bookname, author, publisher } = serialize(editForm, { hash: true, empty: false });
axios.put(`http://hmajax.itheima.net/api/books/${id}`, {
bookname,
author,
publisher,
creator
}).then(res => {
console.log(res);
getBookList();
}).catch(error => {
console.log(error);
});
document.querySelector('.fom2').style.display = 'none';
}
3.编辑按钮监听事件
跟删除一样,都是动态生成的,所以需要通过父元素事件委托绑定点击事件,用于编辑表单的显示
document.querySelector('.list').addEventListener('click', e => {
if (e.target.classList.contains('sp1')) {
const id = e.target.parentNode.dataset.id;
editBook(id);
}
});
4.绑定事件
编辑表单中的确认和取消同样绑定监听事件,确定选项中绑定了阻止表单默认提交,和调用updateBook()函数,更新编辑后的数据,取消按钮设置表单隐藏
document.querySelector('.yes2').addEventListener('click', event => {
event.preventDefault();
updateBook();
});
document.querySelector('.no2').addEventListener('click', event => {
event.preventDefault();
document.querySelector('.fom2').style.display = 'none';
});
总结
通过js操作原生dom实现一个简易的图书管理系统,使用axios对后端数据进行了交互,通过serialize简化了获取表单数据,是一个练手不错的小项目,源码地址如下文件夹里的bookList