文章目录
一、Vue的基本使用
二、Vue的生命周期
三、v-model指令
四、v-bind跳转指令
五、-v-if的使用
六、v-show的使用
七、v-if和v-show的区别
八、v-for
九、侦听器
十、cookie
十一、localStorage
十二、sessionStorage
十三、JSON字符串
十四、JSON和js对象互相转换
十五、计算属性
十六、事件和事件流
十七、事件冒泡和事件捕获
十八、AJAX
一、Vue的基本使用
<body>
<div id="app">
<p> {{msg}} </p>
</div>
<!-- 导入vue.js -->
<script src="./vue.js"></script>
<script>
// <!-- 实例化一个vue -->
new Vue ({
// el获取数据
el:"#app",
// id选择器用#,class选择器用点.号
data:{
msg:"nice day"
}
})
</script>
</body>
二、Vue的生命周期
Vue有八个生命周期
1.第一阶段(创建阶段): beforeCreate,created
2.第二阶段(挂载阶段): beforeMount,mounted
3.第三阶段(更新阶段): beforeUpdate,updated
4.第四阶段(销毁阶段): beforeDestroy,destroyed
<body>
<div class="eg">
{{message}}
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:".eg",
data:{
message:"math"
},
// 创建前
// 在实例完全被创建出来之前,Vue实例的挂载元素el和数据对象data都为undefined,还未初始化。
beforeCreate(){
console.log("beforeCreate");
},
// 创建后
// 数据对象data已存在,可以调用methods中的方法,操作data中的数据,但dom未生成,$el未存在。
created(){
console.log("created");
},
// 挂载前
// Vue实例的$el和data都已初始化,挂载之前为虚拟的dom节点,模板已经在内存中编辑完成了。但是尚未把模板渲染到页面中。
beforeMount(){
console.log("beforeMount");
},
// 挂载后
// vue 实例挂载完成,data.message 成功渲染。内存中的模板,已经真实的挂载到了页面中,
// 用户已经可以看到渲染好的页面了。实例创建期间的最后一个生命周期函数,
// 当执行完 mounted 就表示,实例已经被完全创建好了,DOM 渲染在 mounted 中就已经完成了。
mounted(){
console.log("mounted");
},
// 更新前
// 当 data 变化时,会触发beforeUpdate方法 。data 数据尚未和最新的数据保持同步。
beforeUpdata(){
console.log("beforeUpdata");
},
// 更新后
// 当 data 变化时,会触发 updated 方法。页面和 data 数据已经保持同步了。
updated(){
console.log("updated");
},
// 销毁前
//组件销毁之前调用 ,在这一步,实例仍然完全可用。
beforeDestroy(){
console.log("beforeDestroy");
},
// 销毁后
// 组件销毁之后调用,对 data 的改变不会再触发周期函数,vue 实例已解除事件监听和 dom绑定,但 dom 结构依然存在。
destroyed(){
console.log("destroyed");
}
})
</script>
</body>
三、v-model指令
示例
<body>
<div id="app">
<!-- 输入框 -->
<input type="text" v-model="msg">
<!-- {{msg}} -->
<!-- 下拉框 -->
<select v-model="name">
<option value="dandan">丹丹</option>
<option value="xiaomin">小敏</option>
<option value="lili">莉莉</option>
</select>
<!-- 复选框 -->
<input type="checkbox" v-model="box">
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
msg:"请输入内容",
name:"",
box:""
}
})
</script>
</body>
效果展示

四、v-bind跳转指令
<body>
<div id="app">
<a href="https://www.youkuaiyun.com/">跳转到csdn</a>
<a v-bind:href="url">跳转</a>
<button @click="change" target="_blank">改变网址</button>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
url:"https://www.baidu.com/"
},
methods:{
change(){
this.url="https://www.youkuaiyun.com/"
}
}
})
</script>
</body>
效果展示

第一个链接点击可以跳转到csdn,第二个链接点击可以跳转到百度网址,如果按改变网址这个按钮,就可以点击跳转到csdn这个网址,后面又会变回百度这个网址的链接。
v-model和v-bind的区别
1、v-bind是单向绑定,用来绑定数据和属性以及表达式,数据只能从data流向页面。
2、v-model是双向绑定,数据能从data流向页面,也能从页面流向data。
3、v-bind可以给任何属性赋值,v-model只能给表单类,也就是具有value属性的元素进行数据双向绑定,如text、radio、checkbox、selected。
五、v-if的使用
<body>
<div id="app">
<!-- 多分支 -->
<h1>成绩分布</h1>
<div v-if="score >=90">超优秀</div>
<div v-else-if="score >=80">优秀</div>
<div v-else-if="score >=60">一般</div>
<div v-else="score <60&&>0">不及格</div>
<hr>
<!-- 双分支 -->
<div v-if="age>=18">成年</div>
<div v-else>未成年</div>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
score:92,
age:20
}
})
</script>
</body>
六、v-show的使用
<body>
<div id="app">
<!-- 多分支 -->
<h1>成绩分布</h1>
<div v-show="score >=90">超优秀</div>
<div v-show="score >=80">优秀</div>
<div v-show="score >=60">一般</div>
<div v-show="score <60">不及格</div>
<hr>
<!-- 双分支 -->
<div v-show="age>=18">成年</div>
<div v-show="age<18">未成年</div>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
score:78,
age:20
}
})
</script>
</body>
七、v-if和v-show的区别
[v-show]
1.本质就是标签display设置为none控制隐藏。只是基于CSS进行切换。
2.v-show有更高的初始渲染消耗。
3.v-show适合频繁切换的情况。
[v-if]
1.动态的向DOM树内添加或删除DOM元素。
2.v-if有更高的切换消耗。
3.v-if适合运行条件很少改变的情况。
示例
<body>
<div id="app">
<div v-show="display">由v-show控制</div>
<div v-if="display">由v-if控制</div>
<!-- v-if取的名字和v-show一样 -->
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
display:true
}
})
// display设置为false时
// <div v-show="display">由v-show控制</div>变成<div style="display:none;">由v-show控制</div>
// <div v-if="display">由v-if控制</div>变成<!---->
// display设置为true时
// <div v-show="display">由v-show控制</div>为<div style>由v-show控制</div>
// <div v-if="display">由v-if控制</div>为<div>由v-if控制</div>
</script>
</body>
八、v-for
v-for遍历数组
<body>
<div id="app">
<!-- 实现在最后添加元素 -->
<button v-on:click="add">点击后添加元素</button>
<ul>
<li v-for="(item,index) in list">{{index}}-{{item}}</li>
<!-- in list表示在list中遍历元素,但是现在是在内部遍历,不会显示
为了显示到外部,要用插值表达式 -->
</ul>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
list:["lili","dandan","bobo","balalaa"]
},
methods:{
add(){
this.list.push('adadaaa')
// 在list中添加元素
}
}
})
</script>
</body>
v-for遍历对象
<body>
<div id="app">
<!--
语法:v-for="(val,key) in 对象名"
v-for="val in 对象名" -->
<ul>
<li v-for="item in obj">{{item}}</li>
<hr>
<li v-for="(val,key) in obj">{{val}}--{{key}}</li>
<!-- 不管(val,key)里面写的是啥,这个语法固定前面显示值,后面显示属性名,与名字无关 -->
</ul>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
obj:{
name:"lili",
age:22,
sex:"女"
}
}
})
</script>
</body>
v-for遍历数字
<body>
<div id="app">
<ul>
<li v-for="num in 9">{{ num }}</li>
<!-- in 9 就是遍历从1遍历到9 -->
</ul>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:"#app"
})
</script>
</body>
v-for中key的作用
<body>
<div id="app">
<button v-on:click="list.splice(1,0,{id:4,name:'ekke'})">添加</button>
<!-- splice(1,0,{id:4,name:'ekke'})第一个元素是,从下标1开始删除
第二个元素是,删除0个元素
第三个元素是,添加{id:4,name:'ekke'} -->
<!--
但是现在如果勾选了lalakaka,再添加ekke,就会变成勾选了ekke,lalakaka没勾选
原因:v-for会尝试最大限度的复用当前元素,导致状态绑定错乱
解决方法:在v-for后加上一个key属性,key绑定这个数据的唯一值(一般是id,不能是字符串和数字类型) -->
<ul>
<li v-for="item in list" :key="item.id">
<input type="checkbox">
<span>{{item.name}}</span>
<!-- 要渲染的放进span -->
</li>
</ul>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:"#app",
data:{
list:[
{id:1,name:"babalalaa"},
{id:2,name:"lalakaka"},
{id:3,name:"kalala"},
]
}
})
</script>
</body>
九、侦听器
侦听器的基本结构
<body>
<script>
// 侦听器用来听数据有没有变化,一旦有变化就会调用函数
// 语法:watch和data,methods平级
new Vue({
el:"",
data:{},
methods:{},
watch:{
要侦听的数据(newvalue,oldvalue){
// 参数一:改变后的值
// 参数二:改变前的值
}
}
})
</script>
</body>
侦听器的基本使用
<body>
<div id="app">
<button @click=" msg='hello' ">点击改变msg的值</button>
<p> {{msg}} </p>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
msg:'hi'
},
// 写侦听器的地方
watch:{
// 可以侦听数据的变化
// 基本数据类型,这两个参数有意义
msg(newValue,oldValue){
// 侦听到数据变化后,完成的行为
console.log(oldValue,'变成了',newValue);
}
}
})
</script>
</body>
侦听器在数组中的使用
//对数组进行侦听
// 数组是引用类型,存在比较复杂的侦听类型。
// 从理论上说,修改一个数组的内容,比如修改数组中某个元素的值, 或者给数组添加新的元素,都不会修改数组本身的地址。
// 为此,Vue.js对数组做了特殊处理,使得使用标准的数组操作方法对数组所做的修改,都可以被侦听到。
<body>
<div id="app">
<button @click="list.push('2025')">添加年份</button>
<button @click="list.pop()">删除年份</button>
<!-- 利用索引值改变数组时,不能被侦听到 -->
<button @click="list[0] = '2002' ">修改第一项</button>
<button @click="list.splice(1,0, '2018' )">第二项添加</button>
<ul>
<li v-for="item in list"> {{item}} </li>
</ul>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
list:['2022','2023','2024']
},
watch:{
list(newValue,oldValue){
console.log(oldValue,'变成了',newValue);
}
}
})
</script>
</body>
笔记1
Vue不能检测以下数组的变动
a.当你利用索引值直接设置一个数组时,例如 vm.items[indexOfItem]= newValue
b.当你修改数组的长度时,例如:vm.items.length = newLength
笔记2
使用标准方法修改数组可以被侦听到
push()尾部添加
pop()尾部删除
unshift()头部添加
shift()头部删除
splice()删除、添加、替换
sort()排序
reverse()逆序
Vue将被侦听到的数组的变更方法进行了包裹,所以它们也将会触发视图更新,以上就是被包裹的方法
总结
在数组中使用侦听器总结:
1.彻底替换为一个新数组,就可以被侦听到。
2.如果使用了push()等标准的数组操作方法,那么可以被侦听到。
3.如果直接修改数组的元素,那么无法被侦听到。
(解决方法:使用$set()方法修改元素的值。Vue3语法)
不要使用length属性来改变数组长度,而改用其他标准方法显示数组长度的变化。
侦听器在对象中的使用
<body>
<div id="app">
<p> {{obj.name}}-{{obj.age}}-{{obj.height}} </p>
<button @click=" obj.name = 'rose' ">修改obj的name属性</button>
<button @click=" obj.age = '18' ">修改obj的age属性</button>
<button @click=" obj={name:'zhudi',age:18 } ">修改obj的指向</button>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
obj:{
name:'lili',
age:17,
height:168
}
},
watch:{
// 这种写法侦听不到obj对象内部属性的变化
// 智能侦听到obj对象指向的变化。
// obj(){
// console.log('obj变化了');
// }
// 如果想侦听到对象里属性的变化
// 侦听obj里name的变化((记得加引号))
// "obj.name"(){
// console.log('name变化了');
// }
// but这样只能侦听一个属性
// 如果希望侦听到对象里所有属性的变化,就要开启“深度侦听”
obj:{
// 当有变化会调用的函数
handler(){
console.log('obj的属性变化了');
},
// 开启深度侦听
deep:true,
// ps.不要当前页面一打开就立即调用handler函数,
// 给true表示立即调用,默认是flase(代表,只有改动了才调用)
// immediate:true
}
}
})
</script>
</body>
十、cookie
一、cookie的使用场景:
1.记住密码,下次自动登录。
2.记录用户浏览数据,进行商品(广告)推荐
二、特点:
1.cookie保存在浏览器端。
2.单个cookie保存的数据不能超过4KB
3.cookie中的数据是以域名的形式进行区分的
4.cookie中的数据是有过期时间的,超过时间数据会被浏览器自动删除
5.cookie中的数据会随着请求被自动发送到服务器端
三、
由于cookie存储机制有很多缺点,HTML5不再使用它,转而使用改良后的WebStorage存储机制
WebStorage存储机制就是localStorage和sessionStorage
十一、localStorage
什么是localStorage
在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储使用
它解决了cookie存储空间不足的问题,每条cookie的存储空间为4KB,localStorage一般为5M
localStorage的生命周期
localStorage的生命周期是永久,这意味着除非用户在显示在浏览器提供的UI上清除localStorage信息
否则这些信息将永久存在
localStorage的局限
1.在IE8以上的IE版本才支持localStorage这个属性
2.目前所有的浏览器中都会被localStorage的值类型限定为string类型
判断浏览器是否支持localStorage属性
if(window.localStorage){
alert('浏览器支持localStorage')
}
localStorage的三种写入方法
if(!window.localStorage){
alert('浏览器不支持localStorage')
}else{
var storage = window.localStorage;
// 写入A字段
storage['A'] = 'aaa';
// 写入B字段
storage.B = 'bbb';
// 写入C字段
storage.setItem('C','ccc')
console.log(typeof storage['A']);//string
console.log(typeof storage['B']);//string
console.log(typeof storage['C']);//string
}
十二、sessionStorage
sessionStorage的生命周期
sessionStorage生命周期为当前窗口或标签页
意思就是:一旦窗口或标签页被永久关闭了,那么所有通过session存储的数据也就被清空了
十三、JSON字符串
JSON和JS对象的关系
JSON是JS对象的字符串表示法,它使用文本表示一个JS对象的信息,本质是一个字符串
JS对象的例子
var obj = { a:'hello',b:'world' };
console.log(typeof(obj));//object
JSON的例子(本质是个字符串)
var json = "{ a:'hello',b:'world' }";
console.log(typeof(json));//string
十四、JSON和js对象互相转换
JSON.parse()方法,实现从JSON字符串转换为JS对象
var obj = JSON.parse(' { "a":"hello","b":"world" } ')
console.log(obj);//object
JSON.stringify()方法,实现从js对象转换为JSON字符串
var json = JSON.stringify({ "a":"hello","b":"world" })
console.log(json);//{"a":"hello","b":"world"}(是个字符串类型)
十五、计算属性
!计算属性
可以在里面写一些计算逻辑的属性
它不像普通函数那样直接返回结果,而是经过一系列计算之后再返回结果
同时只要在它当中应用了data中某个属性,当这个属性发生变化时,计算属性可以嗅到这种变化,并自动执行
计算属性的定义和使用
定义:要用的属性不存在,通过已有属性计算得来
使用:在computed对象中定义计算属性,在页面中使用{{方法名}}来显示计算的结果
计算属性的基本结构
new Vue({
el:'',
// 数据
data:{},
// 方法属性
// 事件绑定,不用return,没有缓存
methods:{},
// 侦听器(重视过程)
// 监听一个值的改变,不用返回值
watch:{
要侦听的数据(){}
},
// 计算属性(重视结果)
// 必须有return,只求结果,有缓存
computed:{
计算属性名(){
// 经过一系列计算
return 处理操作后结果
}
}
})
计算属性的缓存特性
第一次调用计算属性时,会产生一个结果,这个结果会被缓存起来,后面每次用这个属性都是从缓存里取
当它的依赖项发生改变时,会重新计算得到一个结果,再缓存起来
计算属性的基本使用
<body>
<div id="app">
<p>原始字符串:{{message}}</p>
<p>计算反转后的字符串:{{reverseMessage}} </p>
<p>将原字符串转为小写:{{ toLowerCase }} </p>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
message:'ABCDEFG'
},
computed:{
// 计算反转后的字符串
reverseMessage:function(){
// split()把一个字符串分割成字符串数组
// reverse()颠倒数组中元素的顺序
// join()把数组中的所有元素转化为一个字符串
return this.message.split('').reverse().join('')
},
// 将原字符串转换为小写
toLowerCase(){
// substring(from,to)提取字符串中介于两个指定下标之间的字符
// toLowerCase()用于把字符串转化为小写
return this.message.substring(0,7).toLowerCase()
}
// !将原字符串的第一个字母转化为小写
// this.message.substring(0,1).toLowerCase+message.substring
}
})
</script>
</body>
计算属性的完整结构
1.每一个计算属性都包含一个getter函数与setter函数
2.计算属性会默认使用getter函数,setter函数并不常见,所以一般计算属性getter和setter都不写
3.gette r函数是默认用法,setter函数不是默认用法。如果要使用setter函数,必须手动写出setter函数
4.setter函数内的形参是你要修改的值
<body>
<div id="app">
姓:<input type="text" v-model="lastName" ><br>
名:<input type="text" v-model="firstName" ><br>
全名:<span> {{fullName}} </span><br>
<button @click="btn" >修改计算属性的值</button>
</div>
<script src="./vue.js"></script>
<script>
new Vue({
el:'#app',
data(){
return{
firstName:'小魔仙',
lasrName:'巴啦啦',
}
},
computed:{
fullName:{
// get:获取值时触发
// 当有人读取fullName时,get就会被调用,且返回值就作为fullName的值
get(){
return this.firstName + '-' +this.lastName;
},
// set:设置值时触发
// 当计算机属性被修改时,调用set
set(value){
console.log('set',value);
}
}
},
methods:{
btn(){
this.fullName = '黑魔仙';
}
}
})
</script>
</body>
十六、事件和事件流
【事件】
JavaScript中的事件,可以理解就是在HTML文档或者浏览器中发生的一种交互操作,使得网页具备互动性。
常见的有加载事件、鼠标事件。
【事件流】
由于DOM是一个树结构,如果在父子节点绑定事件时候,当触发子节点的时候,就存在一个顺序问题,这就涉及到了事件流。
页面触发一个事件时,会按照一定的顺序来响应事件,事件的响应过程为事件流。
【js的事件流三阶段】
事件捕捉阶段(capture phrase):事件开始由顶层对象触发,然后逐级向下传播,直到目标元素;
处于目标阶段(target phrase):处于绑定事件的元素上;
事件冒泡阶段(bubbling phrase):事件由具体的元素先接收,然后逐级向上传播,直到不具体的元素;
(事件捕获是从上到下,而事件冒泡,是从下到上。)
十七、事件冒泡和事件捕获
首先,事件冒泡和事件捕获分别由微软和网景公司提出,是为了解决页面中事件流(事件发生顺序)的问题。
事件冒泡:
// 微软提出了名为事件冒泡(event bubbling)的事件流。
// 事件冒泡可以形象的比喻成把一颗石头投入水中,泡泡会一直从水底冒出水面。
// 也就是说,事件会从最内层的元素开始发生,一直向上传播,直到document对象。
// 因此在事件冒泡的概念下在button按钮发生click事件的顺序应该是button→div→body→html→document.
事件捕获:
// 网景提出另一种事件流名为事件捕获(event capturing)。
// 与事件冒泡相反,事件会从最外层开始发生,直到具体的元素。
// 因此在事件捕获的概念下在button按钮发生click事件的顺序应该是document→html→bodv→div→button。
后来W3C采用折中的方式,平息了网景和微软之间的战争,制定了统一的标准--先捕获在冒泡。
十八、AJAX
认识AJAX
1.Ajax是什么?
"Asynchronous Javascript And XML”(异步JavaScript和XML)
Ajax就是让浏览器跟服务器交互的一套API。
它的作用就是让浏览器和服务器进行交互。
是向服务器请求数据的们局部刷新页面的技术。
2.学习Ajax的目标是什么?
学会使用Ajax根据接口文档和服务器交互。
目前,我们网页所有的数据都是写死的。实际开发中,网页的数据需要从服务器获取
而Ajax技术就是来实现这一功能的。
Ajax的工作流程
<body>
<script>
// 1.创建一个对象
let xhr = new XMLHttpRequest()
// 2.调用xhr对象的open方法,设置请求方式和请求地址
xhr.open('get','https://autumnfish.cn/api/joke')
// 3.设置请求成功后的回调函数
xhr.onload = function(){
// 在这里设置请求成功后要做的事情
console.log(xhr.response);
}
// 4.调用这个对象的send方法
xhr.send();
</script>
</body>
Ajax发送 get 请求
<!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>
<style>
body {
text-align: center;
}
input {
border: 4px solid gray;
padding: 10px;
font-size: 25px;
background-color: skyblue;
color: white;
border-radius: 10px;
cursor: pointer;
outline: none;
}
.joke-container {
width: 500px;
height: 500px;
border: 1px solid gray;
border-radius: 10px;
padding-left: 10px;
margin: 10px auto;
font-size: 30px;
text-align: left;
text-indent: 60px;
}
</style>
</head>
<body>
<input type="button" value="点我获取笑话" class="getJoke">
<div class="joke-container"></div>
<script>
document.querySelector('.getJoke').onclick = function () {
// 1.通过new关键字创建一个网络请求对象
let xhr = new XMLHttpRequest()
// 2.调用xhr对象的open方法,设置请求方式和请求地址
xhr.open('get', 'https://autumnfish.cn/api/joke')
// 3.设置请求成功后的回调函数
xhr.onload = function () {
// 在这里设置请求成功后要做的事情
// console.log(xhr.response);
// 把返回的数据(笑话)显示在div中
document.querySelector('.joke-container').innerHTML = xhr.response;
}
// 4.调用这个对象的send方法
xhr.send();
}
</script>
</body>
</html>
get 请求提交参数
流程:
1.实例化一个请求对象。
2.调用open方法,设置请求方式和请求地址
3.设置请求完成后到回调函数
4.调用send方法,完成请求。
<body>
<!--
-->
<script>
// AJAX发送get请求,如何传递参数
// 拼接在URL地址上
// 格式:url地址?key = value
// url地址?key1=value1&key2=value2&key3=value3
// 1.创建请求对象
let xhr = new XMLHttpRequest
// 2.调用open方法,设置请求方法和请求地址
xhr.open('get','https://autumnfish.cn/api/joke/list?num=5')
// 3.调用onload方法,设置请求完成后到回调函数
xhr.onload = function(){
// console.log(xhr.response);//这样打印出来的5条笑话都堆在一起
let jokes = JSON.parse(xhr.response)//这样打印出来就把5条笑话列在一起
console.log(jokes);
}
// 4.调用send方法,完成请求
xhr.send()
</script>
</body>
Ajax发送post请求
流程:
1.实例化请求对象
2.调用open方法,传递请求方法以及请求地址
3.设置请求头
4.设置请求成功后的回调函数
5.调用send方法
<body>
<!--
get请求传递参数:
直接在url地址后拼接,安全性不高
post请求传递参数:
在send()方法里传递
-->
<script>
// 1.实例化请求对象
let bll = new XMLHttpRequest
// 2.调用open方法,传递请求方法以及请求地址
bll.open('post','https://autumnfish.cn/api/user/register')
// 3.设置请求头
bll.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
// 4.设置请求成功后的回调函数
bll.onload = function(){
console.log(bll.response);
let name = JSON.parse(bll.response)//这样打印出来就把5条笑话列在一起
console.log(name);
}
// 5.调用send方法(发送请求)
// 请求的格式:'key = value'
bll.send('username=llll')
</script>
</body>