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>Document</title>
</head>
<body>
<input type="text" name="" id="mytext">
<button id="myadd">add</button>
<ul class="list">
</ul>
<script type="module">
import ajax from './05utils.js'
// console.log(ajax)
class TodoList {//以列表为对象操作
constructor(select) {
this.listEle = document.querySelector(select)
this.listdata = []//列表数据
this.init()
}
init() {
// 初始化
this.bindEvent()
// 获取数据的方法
this.getList()
}
// 绑事件函数
bindEvent(){
this.listEle.onclick = (evt)=>{
// console.log(evt.target)
if(evt.target.nodeName==="BUTTON"){//删除按钮
this.removeItem(evt.target)
}
}
}
getList() {
// 获取数据
ajax({
url: "http://localhost:3000/list",
success: (res) => {//箭头函数没有this,指向父亲
// console.log(res)
console.log(this)
this.listdata = res
this.render()//渲染页面
},
error: function () {
}
})
}
// 渲染页面
render() {
// console.log("render")
this.listEle.innerHTML = this.listdata.map(item =>
`<li>
${item.text}
<button data-index=${item.id}>Del</button>
</li>`
).join()
}
addItem(text) {
// console.log(text)//拿到输入框的值
// 先在“数据库”添加产生id值后,成功回调中,才能根据id在页面添加
ajax({
url:`http://localhost:3000/list`,
method:"POST",
data:{
// text:text
text
},
success:(res)=>{
console.log("成功",res)
// location.reload()//全局刷新页面不可取
this.listdata = [...this.listdata,res]
this.render()
},
error:function(){
}
})
}
removeItem(target) {
target.parentNode.remove()
// console.log(target.dataset.index)//拿到删除按钮的id
//删除任务
ajax({
url:`http://localhost:3000/list/${target.dataset.index}`,
method:"DELETE",
success:(res)=>{
console.log("删除成功!")
},
error:function(){
}
})
}
updataItem() {
}
}
var obj = new TodoList(".list")
// console.log(obj)
myadd.onclick = function(){
obj.addItem(mytext.value)
}
</script>
</body>
</html>
2.Ajax封装(05utils.js):
// 将对象数据进行截取,使之成为字符串拼接格式
function queryStringfy(obj){
let str =''
for(let k in obj) str+=`${k}=${obj[k]}&`
return str.slice(0,-1)
}
// 封装Ajax
function ajax(options){
let defaultoptions = {
url:"",
method:"GET",
async:true,
data:{},
headers:{
"content-type":"application/x-www-form-urlencoded"
},
success:function () {},
error: function () {}
}
let { url, method, async, data, headers, success, error } ={
...defaultoptions,
...options
}
console.log(url,method,async,data,headers,success,error)
// post
// 数据为对象且headers里面的字符串包含json,?代表取不到content-type就不.indexOf了
if(typeof data ==='object' && headers["content-type"]?.indexOf("json")>-1){
data = JSON.stringify(data)
}else{
data = queryStringfy(data)
}
// get传参,并且有参数,组装一下url信息
if(/^get$/i.test(method)&&data) url +='?' + data
// 发送请求
const xhr = new XMLHttpRequest()
xhr.open(method,url,async)
xhr.onload = function(){
if(!/^2\d{2}$/.test(xhr.status)){
error(`错误状态码:${xhr.status}`)//回调
return
}
// 执行解析
try{
let result = JSON.parse(xhr.responseText)
success(result)//回调
}catch(err){
error('解析失败!因为后端返回的结果不是json格式字符串')//回调
}
}
// 请求头中的内容不止一项
for(let k in headers) xhr.setRequestHeader(k,headers[k])
if(/^get$/i.test(method)){//get
xhr.send()
}else{
xhr.send(data)//post
}
}
export default ajax
3.使用json-server(基于一个json文件就可以创建后端模拟接口):
命令行:json-server .\07test.json --watch
{
"list": [
{
"text": "aaa",
"id": 1
},
{
"text": "bbb",
"id": 2
}
]
}
4.结果展示:
(1)删除aaa:
(2)添加:
但是此处有个小bug:因为源码中使用展开运算符添加新的内容,再渲染页面,导致渲染时aaa还在页面中,点击刷新aaa就不会在页面中显示了。
this.listdata = [...this.listdata,res]
this.render()