Unit-01
一. 执行环境,变量对象以及作用域
1. 执行环境
-
js代码的执行环境:
-
全局执行环境(默认)
-
函数执行环境 ( 调用函数的时候, 就会创建函数的执行环境 )
-
js的执行环境,会被放入一个栈中, 默认栈中放的是全局执行环境, 当有函数调用, 就会创建函数的执行环境,且把这个执行环境推入栈中 ( 栈: 执行环境栈 或 调用栈 )
2. 变量对象
- 每个执行环境,都会关联一个看不见的 变量对象
- 变量对象,存着这个执行环境中的所有标识符
- 标识符:变量名 / 函数名 / 形参 / 对象的键名
- 当执行环境销毁, 关联的变量对象也会把所有标识符销毁
3. 作用域
3.1 概念:
- 标识符可以使用的范围 (自己作用域和子作用域 )
3.2 作用域链
- 提供了一套规则, 从里往外(函数声明的大括号)查找标识符, 找到就可以使用,找不到就报错
3.3 作用域分类
- 全局
- 局部(函数作用域)
- 块作用域
二. 函数进阶
1. 函数的写法
-
声明式写法
function 函数名(形参) { // 执行代码 } ``` -
表达式写法
const 变量 = function(形参) { // 执行代码 } ``` -
箭头函数
-
形参有且只有1个,可省略() [ 也可以不省略 ] (不建议小括号)
-
执行代码只有1句,可省略{}, 且必须省略return, 会自动return [ 也可以不省略 ]
const 变量 = (形参) => { // 执行代码 } -
2. 函数的参数
-
形参与实参
- 形参:占位使用, 要语义化, 叫啥都行
- 实参:调用函数,实际传入的参数,传入的参数需要和形参一一对应
-
默认参数:
-
es5写法
function fn(param) { let temp = param || 默认值 } ``` -
es6写法
function fn(param = 默认值) { } ```
-
-
arguments
o 在函数内部可以直接获取到, 获取到所有实参, 结果是:伪数组
o 作用: 不能确定参数个数的情况
-
rest剩余参数
- es6推出的, 叫: 剩余参数. 用来取代arguments
function 函数名(形参1, ...形参) {
// 形参1: 得到实参1
// 形参: 得到 [实参2, 实参3, 实参4]
}
函数名(实参1, 实参2, 实参3, 实参4)
3. 函数的返回值
-
函数没有return, 默认return undefined
-
函数返回啥,就得到啥.
-
哪里调用函数, 函数的返回值,就返回到那里去.
-
函数都要return吗?
-
如果调用一个函数, 只是让它干一件事, 干就完了, 不要结果, 就不需要return
渲染函数
弹窗函数
-
如果调用一个函数, 需要它把结果汇报给你, 要使用变量接收这个结果, 把结果用在别的地方.
求和
获取年月日
-
4. 函数的调用
-
直接调用 ---直调
function 函数名() {} 函数名() const 变量 = function() {} 变量() ``` -
对象里的函数 -- 对调
let obj = { 函数名: function() {} } obj.函数名() ``` -
回调函数: 当满足一定条件,自动调用执行 - 回调
setTimeout(function() { console.log(666); }, 1000) dom.addEventListener("click", function() { console.log(888) }) ``` -
IIFE立即执行函数表达式 - 自调
;(function() { // 执行代码 console.log(666) })() ```
三. 闭包
1. 闭包的概念
- 函数跨作用域访问变量,形成闭包. 闭包是一种作用域的体现. 一般把: 函数 和 变量 的总和,称为闭包
2. 闭包的两种标准写法
- 父函数嵌套子函数, 子函数访问父函数的变量,把子函数返回或挂在全局
- 第一种
;(function() {
let 变量1;
function 子函数() {
console.log(变量1)
}
window.属性名 = 子函数
})()
- 第二种
const 变量 = (function() {
let 变量1;
function 子函数() {
console.log(变量1)
}
return 子函数
})();
3. 闭包的作用
- 把变量封闭包裹在一个匿名函数内部, 隐藏变量或私有化变量, 实现早期的模块化
4. 闭包的缺点
- 形成闭包的变量会常驻内存,不被js的垃圾回收机制回收。过多使用闭包,会造成内存开销过大,甚至内存泄漏
Unit-02
一. 面向对象和面向过程
- 面向过程(POP): 按照流程, 一步一步的做, 所有步骤亲力亲为 ----小兵思维
- 面向对象(OOP): 把功能封装成对象, 要做什么找对象,调用对象的方法, 指挥者的思维 ---将军思维
- 类和实例对象
- 类(构造函数): 一个大的分类: 数组 对象 字符串 数字 日期
- 实例对象: 一个非常具体的对象: 小貂蝉 18
const 实例对象 = new 类()
const arr = new Array([1,2,3])
const obj = new Object()
二. 构造函数
- 在es5中, js没有类, 所以使用 构造函数代表类
- JS有内置的构造函数(类)
// 实例化对象( 使用new 调用构造函数 创建出实例对象 )
const obj = new Object()
const arr = new Array()
const num = new Number()
const str = new String()
const date = new Date()
- 构造函数的特点
- 函数名大写字母开头
- 属性和方法都挂在this上
- 没有返回值
- 使用new调用
// 创建一个类:Person
function Person(name, age, sex) {
// 给this添加属性
this.name = name;
this.age = age;
this.sex = sex;
// 给this添加方法
this.eat = function () {
return "干饭"
}
}
-
new的过程
-
创建一个空对象
-
让this指向空对象
-
执行构造函数代码
-
自动返回this
// 创建一个类:Person
function Person(name, age, sex) {
// 给this添加属性
this.name = name;
this.age = age;
this.sex = sex;
// 给this添加方法
this.eat = function () {
return "干饭"
}
}
// p1, p2是返回的实例对象
let p1 = new Person("小貂蝉", 18, "女");
let p2 = new Person("赵子龙", 19, "男");
三. 原型和原型链
1. 方法过载
- new出来的实例对象, 每个实例对象,都有一份自己的方法,称为 方法过载,内存开销过大
2. 原型 prototype
// 创建一个类:Person
function Person(name, age, sex) {
// 给this添加属性
this.name = name;
this.age = age;
this.sex = sex;
}
// 向原型(原型是一个对象)添加方法
Person.prototype.eat = function() {
return "干饭"
}
const p1 = new Person("熊大", 18, "男")
const p2 = new Person("熊二", 17, "男")
console.log(p1);
console.log(p2);
- 每个函数,特指构造函数,都有一个属性prototype,就是原型( 显式原型 )
console.log("原型1:",Person.prototype);
- 原型prototype是一个对象, 添加在里面的方法,被所有new出来的实例对象共享
console.log("原型2:",p1.eat === p2.eat) // 方法是共享的
- 实例对象,都有一个属性
__proto__(隐式原型), 等于自己构造函数的prototype(显式原型)
console.log("原型3:", p1.__proto__===Person.prototype, p2.__proto__===Person.prototype)
- 原型prototype里面有一个属性constructor, 指向构造函数本身
console.log("原型4:",Person.prototype.constructor === Person)
注意:浏览器无法显示实例对象的__proto__属性,而是以[[Prototype]]代替__proto__
3. 原型的作用
- 添加共享方法
Person.prototype.eat = function() {
return "干饭"
}
4. 原型链
- 原型prototype本身也是一个实例对象, 也有
__proto__, 指向自己构造函数Object的prototype
console.log("原型5:",Person.prototype.__proto__===Object.prototype)
- Object的prototype也是实例对象, 也有
__proto__, 指向null
console.log("原型6:",Object.prototype.__proto__)
- Object的prototype也有属性constructor, 指向构造函数Object本身
console.log("原型7:",Object.prototype.constructor === Object)
5. 原型链的作用
- 添加共享方法
- 实例对象查找方法,先找自己,自己没有,就沿着原型链往上找,找到就可以调用,直到Object.prototype找不到就报错
6. 图解
四. this
1. this的指向
- 全局this: window
- 函数中的this: 谁调用,指向谁
- 对象方法中的this: 谁调用,指向谁
- 构造函数中的this: 实例对象
- 事件处理函数中的this: 事件源
- 定时器中的this: window
- 箭头函数中的this: 上一级 ( 箭头函数没有this, 它的this绑定定义函数时所处的作用域 )
2. 3个改变this指向的方法
- call() 和 apply(): 功能一模一样, 唯一的区别是传递参数方式不同
# 语法
函数名.call(this指向, 实参1, 实参2) // 调用函数 且 指定this
函数名.apply(this指向, [实参1, 实参2]) // 调用函数 且 指定this
- bind():把函数的this绑定到一个目标对象,然后返回一个新函数, 此后,只要调用新函数, this就固定了,指向之前绑定的目标对象
const 新函数 = 函数.bind(this指向)
新函数()
Unit-03
一. 基本类型和引用类型
1. js的数据类型
- 基本类型:string,number,null,undefined,boolean,symbol,bigint
- 引用类型:object (object, function,array)
2. 数据类型的内存分配
- 基本类型: 存放在 栈内存 中
- 引用类型: 存放在 堆内存中, 栈中存它的 地址 , 地址指向堆中的数据
3. 变量的复制和参数的传递
- 基本类型: 复制和传递的是 值的拷贝
- 引用类型: 复制和传递的是 地址的拷贝
二. 深浅拷贝
1. 为什么需要深浅拷贝
- 拷贝一个引用类型 的数据 ( 基本都是拷贝: 对象 ),如果直接赋值, 就会共享数据,互相影响
2. 浅拷贝
- 只能拷贝对象的一层
- 方法一: for in
let obj1 = {
name: "小貂蝉",
age: 18,
company: {
name: "源码"
}
}
let obj2 = {}
for (let key in obj1) {
// console.log(key, obj1[key]);
// {name: , age: }
obj2[key] = obj1[key]
}
obj1.name = "老貂蝉"
obj2.name = "子龙"
obj1.company.name = "源码-科技"
console.log(obj1)
console.log(obj2)
- 方法二: - Object.assign()
let obj1 = {
name: "小貂蝉",
age: 18,
company: {
name: "源码"
}
}
let obj2 = Object.assign({}, obj1);
obj2.name = "子龙"
obj2.age = 17
console.log(obj1)
console.log(obj2)
3. 深拷贝
-
方法一: JSON.parse ( JSON.stringify(要拷贝的对象) )
-
缺点:
-
函数和undefined会丢失
-
Infinity 和 -Infinity 会变成null
-
date会从对象格式变成字符串格式
-
reg正则会变成空{}
let obj1 = {
name: "小貂蝉",
age: 18,
company: {
name: "源码"
}
}
// 第一种方法 JSON.parse(JSON.stringify(要拷贝的对象)) ----
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.name = "老貂蝉"
obj1.company.name = "黑马"
obj2.name= "子龙"
console.log(obj1);
console.log(obj2);
- 方法二: _.cloneDeep() // 使用 lodash.js 进行深拷贝
// 引用本地的lodash.js文件
<script src="./lodash.js"></script>
<script>
let obj1 = {
name: "小貂蝉",
age: 18,
company: {
name: "源码"
},
show: function () {
console.log("shower")
},
a: undefined,
b: Infinity,
c: -Infinity,
date: new Date(),
reg: /abc/
}
let obj2 = _.cloneDeep(obj1)
console.log(obj1);
console.log(obj2);
</script>
三. 变量类型检测
1.typeof 检测基本类型
typeof "abc" // string
typeof 12 // number
typeof undefined // undefined
typeof null // object
typeof true // boolean
typeof Symbol() // symbol
typeof 12n // bigint
typeof {} // object
typeof [] // object
typeof function() {} // function
// [] {}这个分不清
function each(param) {
// 1.如果这个param 是数组的话,遍历 , +1
if(如果这个param 是数组的话) {}
// 2.如果是对象的话,把对象的键值打印出来。
if(如果是对象的话,把对象的键值打印出来)
}
2. instanceof 检测引用类型
- 只能用于检测引用类型, 基本类型用不了.
变量 instanceof 构造函数
// 检测前面的变量 是不是 后面构造函数的实例对象
let arr = [];
arr instanceof Array;
let obj = {};
obj instanceof Object;
let fn = function() {};
fn instanceof Function;
3. Object.prototype.toString.call() 完美检测所有类型
- 在Object的prototype原型上,有一个方法, 叫: toString, 可以检测所有变量的类型
Object.prototype.toString.call(变量)
// 使用call调用 指定this 这个方法会输出this的类型信息
Object.prototype.toString.call("abc")
Object.prototype.toString.call(10)
Object.prototype.toString.call(undefined)
Object.prototype.toString.call(null)
Object.prototype.toString.call(false)
Object.prototype.toString.call(Symbol())
Object.prototype.toString.call(10n)
Object.prototype.toString.call([])
Object.prototype.toString.call({})
Object.prototype.toString.call(function fn() {})
- 封装检测类型的函数
function getType(item) {
return Object.prototype.toString.call(item).slice(8, -1);
}
四. ES5继承
- 继承主要指的是类与类之间, 让子类继承父类的一切
- 让子类继承父类所有属性
- 让子类继承父类所有原型方法
- 找回子类构造函数
// 定义一个父类
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.eat = function() {
return "干饭"
}
// 定义一个学生类
function Student(name, age, sex, skill) {
// 1. 继承所有属性
Person.call(this,name, age, sex);
this.skill = skill;
}
// 2. 继承所有原型方法
Student.prototype = Object.create( Person.prototype );
// 3. 找回构造函数
Student.prototype.constructor = Student;
Student.prototype.study = function() {
return "学习"
}
let st1 = new Student("小红", 16, "女", "跳舞")
// 定义一个程序员类
function Iter(name, age, sex, hob) {
// 1. 继承所有属性
Person.call(this, name, age, sex);
this.hob = hob;
}
// 2. 继承所有原型方法
Iter.prototype = Object.create( Person.prototype );
// 3. 找回构造函数
Iter.prototype.constructor = Iter;
Iter.prototype.abi = function() {
return "CV"
}
let it1 = new Iter("华子", 22, "男", "抽华子")
Unit-04
一. 变量的解构赋值
1. 解构数组
- 从数组中取出数据更方便简洁
# ES5
let arr = [1, 2, 3]
let num1 = arr[0];
let num2 = arr[1];
let num3 = arr[2];
# ES6
// 把数组的值 按照顺序 解构出来 赋值给对应的变量
let arr = [1, 2, 3]
let [变量1, 变量2, 变量3] = [1, 2, 3]
2. 解构对象
- 从对象中取出数据更方便简洁
# ES5
let user = {
name: "zs",
age: 30,
sex: "女"
}
let name = user.name;
let age = user.age;
let sex = user.sex;
# ES6
let {name, sex, age} = user; // 通过变量和键名的对应关系 取出对象选中的值 赋值给对应的变量.
3. 解构参数
- 解构参数的本质,就是解构数组和对象
- 参数是数组的情况
function fn([变量1,变量2,变量3]) {
console.log(变量1,变量2,变量3)
}
fn(["a", "b", "c"])
- 参数为对象的情况
function fn({name, age}) {}
let obj = {
name: "zs",
age: 20
}
fn(obj)
二. 展开运算符
1. 展开字符串
const str = 'hello'
console.log( ...str ) // h e l l o 展开成1个1个的
// 字符串变数组
const arr = [...str] // [h, e, l, l, o]
// 字符串变对象
const o = { ...str } // { 0: h, 1:e, 2: l, 3:l, 4: o }
2. 展开数组
const arr = ['a', 'b', 'c']
console.log(...arr) // a b c
// 浅拷贝数组
const arr1 = [...arr]
// 合并数组
const arr2 = [1, 2, 3]
3. 展开对象
const user = {
name: "小甜甜",
age: 18,
sex: "男"
}
console.log(...user) // 报错
// 浅拷贝对象
const user1 = {...user}
// 合并对象
const user0 = {name : "至尊宝", age: 600, sex: "猴", skill: "七十二变"}
const user2 = {...user, ...user0}
4. 展开伪数组
function sum() {
console.log(...arguments)
console.log([...arguments]) // 把伪数组变成了真数组
}
sum(1, 2, 3, 4)
三. 模板字符串
- 解决字符串和js变量拼接问题
- 可以换行
let str = `abc${表达式}def`
# 表达式 与 语句
表达式:一个表达式会产生一个值。它可写在赋值语句等号的右侧。
a + b; // 算出一个值
fn(); // 算出一个值
myvar; // 算出一个值
语句: if() for()
四. 对象的简洁写法
# ES5 写法
let name = "小貂蝉";
let age = 18;
let sex = "女"
let user = {
name: name,
age: age,
sex: sex,
show: function() {
console.log("shower")
}
}
#ES6 写法
let user1 = {
name, // 键名和键值的变量同名 可以省略
age,
sex,
show() { //对象中的方法:可以省略: function以及
console.log("shower")
}
}
五. 类class
1.类的写法
- ES5写类
// 定义一个Person类,使用构造函数实现
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.num = 10;
}
Person.prototype.eat = function() {
return "干饭"
}
// 静态方法: 只能通过类名.方法(),实例对象无法访问
Person.way = function() {
return "走路"
}
let p = new Person("子龙", 17, "男")
- ES6写类
class Person {
num = 10; // num会自动成为实例属性 ( 自动挂在new出来的实例对象上 )
// 构造函数
constructor(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 添加在原型上的方法
eat() {
return "干饭"
}
// 静态方法: 只能通过类名.方法(),实例对象无法访问
static way() {
return "走路"
}
}
let p = new Person("小貂蝉", 18, "女")
2.继承
- ES5:寄生组合式继承
// 定义一个Person 作为父类,使用构造函数实现
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.num = 10;
}
Person.prototype.eat = function() {
return "干饭"
}
// 静态方法: 只能通过类名.方法(),实例对象无法访问
Person.way = function() {
return "走路"
}
// 定义子类 Student
function Student(name, age, sex, skill) {
Person.call(this, name, age, sex); // 1.继承父类的属性
this.skill = skill;
}
Student.prototype = Object.create(Person.prototype) // 2.继承父类原型的方法
Student.prototype.study = function() {
return "学习"
}
Student.prototype.constructor = Student // 3.找回自己的构造函数
Student.way = Person.way; // 4.继承静态方法
- ES6类的继承
class Person {
num = 10;
// 构造函数
constructor(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 向原型上添加方法
eat() {
return "干饭"
}
// 静态方法: 只能通过类名.方法(),实例对象无法访问
static way() {
return "走路"
}
}
class Student extends Person {
constructor(name, age, sex, skill) {
super(name, age, sex) // 1. super必须写在第一行 继承父类的所有属性
this.skill = skill;
}
study() {
return "学习"
}
}
六. ES6的模块化
- 一个js文件,就是一个模块,可以互相导入导出
1. node的模块化 (运行在node环境中)
// 导出(暴露)
module.exports = {
fn,
name,
}
//导入
const r = require(路径或者模块名)
2. ES6的模块化(运行在浏览器环境中)
- 方式一
// 导出
export var num = 10;
export function fn() {}
// 导入
import { num, fn} from '路径'
- 方式二
// 导出
export default {}
// 可以导出任意东西 但是基本上是对象居多
// 这种导出方式 一个js文件 只能使用1次
// 导入
import 变量 from '路径'
Unit-05
一. 同步和异步
1. 概念
- 同步: 代码从上往下执行, 后面的代码, 必须等待前面代码执行完毕,才可以执行
for(let i = 0; i < 50000; i++) {
console.log("排在队伍前的第一人")
}
console.log("第2人")
console.log("第3人")
console.log("第4人")
- 异步: 代码从上往下执行, 如果遇到异步代码, 异步代码会先让开,等待所有同步代码执行完毕,最后才执行
setTimeout(() => {
console.log("排在队伍前的第一人")
}, 5000)
console.log("第2人")
console.log("第3人")
console.log("第4人")
2. js中异步的场景
js的异步, 是通过回调函数实现的
- setTimeout
console.log(1);
setTimeout(function() {
console.log(2)
}, 1000);
setTimeout(function() {
console.log(3)
}, 1100);
console.log(4)
- ajax
console.log(1);
axios.get("https://mock.apifox.cn/m1/1187430-0-default/test1").then((res) => {
console.log(2, res.data)
});
axios.get("https://mock.apifox.cn/m1/1187430-0-default/test2").then((res) => {
console.log(3, res.data)
})
console.log(4)
- 事件处理函数
console.log(1);
document.querySelector("#btn").addEventListener("click", () => {
console.log(666);
})
console.log(2)
二. 回调地狱
1. 概念
- 回调函数 嵌套 回调函数,嵌套层级太多,称为回调地狱
- 注意: 回调地狱对于实现功能,是没有任何问题的, 缺点是: 代码丑/难以维护/可读性差
2. 示例代码
- 什么情况下,会产生回调地狱: 当你要控制异步的顺序 ( 工作中,最常用的是, 控制ajax的顺序 )
// 1.先获取省份 ID
axios.get("http://47.96.154.185:3701/api/shared/province").then((res) => {
console.log(res.data);
let first = res.data.data[0].id;
// 2. 通过省份ID 调接口 取城市 ID
axios.get(`http://47.96.154.185:3701/api/shared/city?provinceId=${first}`).then((res) => {
console.log(res.data);
let second = res.data.data[1].id;
// 3. 把城市ID 提交给服务器 ---- 调接口
axios.get(`https://mock.apifox.cn/m1/1187430-0-default/upload?cityId=${second}`).then((res) =>{
console.log(res.data)
})
})
})
三. Promise
1. 概念
- Promise是一个类(构造函数), 是 ES6 新增的, 主要用来解决 异步问题, 让我们更好的控制 异步的顺序
2. 基本语法
// 创建一个Promise示例
const p = new Promise((resolve, reject) => {
// console.log("resolve", resolve);
// console.log("reject", reject);
// resolve(); // 从进行中 -> 解决
// reject() // 从进行中 -> 拒绝
})
p.then((data) => {
// 上一步调用resolve触发
console.log(data);
}).catch((err) => {
// 上一步调用reject触发
console.log(err);
}).finally(() => {
// 无论是调用resolve,还是reject都会触发。
console.log("最后")
})
3. 原型方法
p.then(function() {
// 从进行中 -> 解决
}).catch(function() {
// 从进行中 -> 拒绝
}).finally(function() {
// promise状态变化,无论是解决还是拒绝,都会执行
})
4. Promise解决回调地狱
- 使用Promise解决回调地狱, 就是解决异步的顺序问题.( 把回调嵌套回调, 改成从上往下的代码 )
// 创建一个promise实例
const p = new Promise((resolve, reject) => {
// 发送第一个 ajax
axios.get("http://47.96.154.185:3701/api/shared/province").then((res) => {
console.log(res.data);
let first = res.data.data[0].id;
resolve(first);
})
})
p.
then((data) => {
console.log(666, data);
return new Promise((resolve, reject) => {
// 发送第二个 ajax
axios.get(`http://47.96.154.185:3701/api/shared/city?provinceId=${data}`).then((res) => {
console.log(res.data);
let second = res.data.data[1].id;
resolve(second);
})
})
})
.then((data) => {
console.log(777, data);
return new Promise((resolve) => {
// 发送第三个ajax
axios.get(`https://mock.apifox.cn/m1/1187430-0-default/upload?cityId=${data}`).then((res) =>{
console.log(res.data)
reslove();
})
})
})
.then(() => {
console.log(888);
})
四. async和await
1. 概念
- async 和 await 是 ES7 新增的两个关键字, 必须配合使用, 是异步的 终极解决方案
- async: 声明函数内部,有异步操作
- await: 等待Promise实例对象状态切换完毕. 得到结果
async function fn() {
await xxx
}
const fn = async function () {
await yyy;
}
const fn = async () => {
await zzz;
}
2. async和await解决回调地狱
async function uploadData() {
// 发送第1个 ajax
// axios.get() 返回了一个promise实例
// 自动了resolve(后端的响应值)
let r1 = await axios.get("http://47.96.154.185:3701/api/shared/province");
console.log(r1.data);
let first = r1.data.data[0].id;
// 发送第2个 ajax
let r2 = await axios.get(`http://47.96.154.185:3701/api/shared/city?provinceId=${first}`);
console.log(r2.data);
let second = r2.data.data[1].id;
// 发送第3个 ajax
let r3 = await axios.get(`https://mock.apifox.cn/m1/1187430-0-default/upload?cityId=${second}`);
console.log(r3.data)
}
uploadData();
五. axios库的使用
1. ### 发送get请求
- 方式一
axios.get("url?参数名1=参数值1&参数名2=参数值2")
.then((res) => {
console.log(res.data)
})
.catch((err) => {
console.log(err)
})
.finally(() => {
})
- 方式二
axios.get("url", {
params: {
参数名1:参数值1,
参数名2:参数值2
}
})
.then((res) => {
console.log(res.data)
})
.catch((err) => {
console.log(err)
})
.finally(() => {
})
- 方式三
axios({
url: "",
method: "get",
params: {}
})
.then((res) => {
console.log(res.data)
})
.catch((err) => {
console.log(err)
})
.finally(() => {
})
2. post的请求方式
- 方式一
axios.post("url", {
参数名1:参数值1,
参数名2:参数值2
})
.then((res) => {
console.log(res.data)
})
.catch((err) => {
console.log(err)
})
.finally(() => {
})
- 方式二
axios({
url: "",
method: "post",
data: {}
})
.then((res) => {
console.log(res.data)
})
.catch((err) => {
console.log(err)
})
.finally(() => {
})
3. 拦截器
- 请求拦截: 发送出去之前,拦截
axios.interceptors.request.use((config) => {
// 操作 config
return config
})
- 响应拦截: 接收到数据之前,拦截
axios.interceptors.response.use((response) => {
// 操作 response
return response
})
4. 并发多个请求
function 第一个ajax() {
return axios.get('/user/12345');
}
function 第二个ajax() {
return axios.get('/user/12345/permissions');
}
axios.all([第一个ajax(), 第二个ajax()])
.then(axios.spread( (r1, r2) => {
// 两个请求现在都执行完成
}));