05 Vue 最终

    科技2023-11-10  95

    文章目录

    一. Promise01 Promise介绍和基本使用02 Promise三种状态03 Promise的链式调用04 Promise的all方法使用 二. Vuex01. Vuex概念和作用解析02. 单界面到多界面状态管理切换03. vue-devtools和mutations04. vue五个核心1. state单一状态树(Single Source of Truth 单一数据源)2. Getters3. mutations3. vuex-actions4. vuex-modules 三. axios01 axios框架的基本使用02 axios发送并发请求03 axios的配置信息相关04 axios的实例和模块封装05 axios拦截器的使用

    一. Promise

    01 Promise介绍和基本使用

    Promise是异步编程的一种解决方案什么时候会处理异步事务? 一种很常见的场景就是网络请求,我们封装一个网络请求的函数,因为不能立即拿到结果,所以我们往往会传入另一个函数,在数据请求成功时,将数据通过传入的函数回调出去,如果只是简单的网络请求可以这样解决,但是当网络请求非常复杂时,就会出现回调地狱。 什么时候会用到Promise? 一般情况下是有异步操作时,使用Promise对这个异步操作进行封装 <script> //new -> 构造函数(1.保存一些状态信息 2.执行传入的函数) //在执行传入的回调函数时,会传入两个参数,resolve,reject,本身它们也是函数 new Promise((resolve,reject)=>{ setTimeout(()=>{ //01 成功的时候调用resolve resolve('hello world') //会把data传给专门处理的函数 //02 失败的时候调用reject('error msg'),不会执行then reject('error msg') },1000) }).then((data)=>{ //网络请求代码和处理代码做了分离 console.log(data); console.log(data); console.log(data); console.log(data); }).catch((err) => { console.log(err); }) </script>

    02 Promise三种状态

    当开发中有异步操作的时候,可以给异步操作包装一个Promise 异步操作后会有三种状态 pending:等待状态,比如正在进行网络请求,或者定时器没有到时间。fulfill:满足状态,当我们主动回调了resolve时,就处于该状态,并且会回调.then()reject:决绝状态,当我们主动回调了reject时,就处于该状态,并且会回调.catch() Promise的另外一种写法 <script> new Promise((resolve,reject)=>{ setTimeout(()=>{ // resolve('hello vuejs') reject('err msg') },1000) }).then(data=>{ //可以在then中同时定义满足的函数和拒绝的函数,省略catch() console.log(data); //调用resolve时执行第一个方法 },err =>{ console.log(err); //调用reject时执行第二个方法 }) </script>

    03 Promise的链式调用

    *原始写法:

    //01 ===== wrapped into =========== //网络请求:aaa -> 自己处理(10行) //处理:aaa111 -> 自己处理(10行) //处理:aaa111222 -> 自己处理 new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('aaa') },1000) }).then(res=>{ //1 自己处理 console.log(res,'第一层的10行处理代码'); //2 对结果进行第一次处理 return new Promise((resolve,reject)=>{ //如果只有resolve,其实reject是可以不写的 // resolve(res+'111') //不需要异步请求,自己处理 reject('err') }) }).then((res)=>{ console.log(res,'第二层的10行处理代码'); return new Promise((resolve)=>{ resolve(res+'222') }) }).then((res)=>{ console.log(res,'第三层的10行处理代码'); }).catch(err => { console.log(err); }) 简写 resolve //02 ============ 其实只有第一次使用了异步操作,二三层只是普通操作,没必要new Promise ============ new Promise(resolve => resolve(结果)) 简写 new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('aaa') },1000) }).then(res=>{ //1 自己处理 console.log(res,'第一层的10行处理代码'); //2 对结果进行第一次处理 return Promise.resolve(res+'111') }).then((res)=>{ console.log(res,'第二层的10行处理代码'); return Promise.resolve(res+'222') }).then((res)=>{ console.log(res,'第三层的10行处理代码'); }) //03 ============= 省略Promise.resolve =========== new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('aaa') },1000) }).then(res=>{ //1 自己处理 console.log(res,'第一层的10行处理代码'); //2 对结果进行第一次处理 return res+'111' //内部会进行包装,调用resolve }).then((res)=>{ console.log(res,'第二层的10行处理代码'); return res+'222' }).then((res)=>{ console.log(res,'第三层的10行处理代码'); }) 简写 reject //reject的简写: new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('aaa') },1000) }).then(res=>{ //1 自己处理 console.log(res,'第一层的10行处理代码'); //2 对结果进行第一次处理 // return Promise.reject('err msg') //01 错误时:Promise.reject(结果) throw 'error msg' //02 也可以手动抛出异常,也可以在catch拿到错误信息 }).then((res)=>{ console.log(res,'第二层的10行处理代码'); return Promise.resolve(res+'222') }).then((res)=>{ console.log(res,'第三层的10行处理代码'); }).catch(err => { console.log(err); })

    04 Promise的all方法使用

    <script> //某个需求需要发送两次网络请求才能完成 Promise.all([ //内部自动判断两个网络请求有没有都完成,都完成则去到then处理 // new Promise((resolve,reject)=>{ // $ajax({ // url:'url1', // success:function(data){ // resolve(data) //有结果则回调resolve // } // }) // }), // new Promise((resolve,reject)=>{ // $ajax({ // url:'url2', // success:function(data){ // resolve(data) // } // }) // }) //模拟同时有两个异步请求 new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve({name:'pao',age:18}) },2000) }), new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve({name:'ko',age:19}) },1000) }) ]).then(results => { //results是一个数组,包含两个请求结果,统一进行处理 console.log(results); // ["result1", "result2"] }) </script>

    二. Vuex

    01. Vuex概念和作用解析

    Vuex是做什么的?

    管理什么状态?(需要在多个界面共享的状态) 例如用户的登录状态,头像,名称或者商品的收藏、购物车里的物品等等。

    02. 单界面到多界面状态管理切换

    使用vuex之前需要先安装 在安装的时候我出现了一个小bug:http自签名失败 按照网上的教程可以解决:

    使用vuex 创建文件夹store(仓库),新建index.js文件

    import Vue from 'vue' import Vuex from 'vuex' //1 安装插件 Vue.use(Vuex) //2 创建对象 const store = new Vuex.Store({ state:{ count:1000 }, mutations:{ }, actions:{ }, getters:{ }, modules:{ } }) //3 导出store对象 export default store //main.js中导入 import Vue from 'vue' import App from './App' import store from './store' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', store, render: h => h(App) }) 重新运行项目 我们不需要使用以前父子组件传值的方法,直接$store.state.count就可以获取在state中保存的值。 <template> <div> <h2>{{$store.state.count}}</h2> </div> </template> <script> export default { name:'HelloVuex', // props:{ // count:Number // } } </script> 这里报错:因为我刚才在cmd终端安装的vuex,vscode可能没有反应过来,所以再安装一遍,安装出错可以试试:npm报错 按教程清一下缓存再安装:成功! 这时就可以npm run dev运行项目了。

    03. vue-devtools和mutations

    vue-devtools的安装:教程分享简单的使用案例: 创建文件夹store,创建index.js文件,我们在state中定义了一个共享的变量count,在mutations中定义了两个方法来控制count的增减。 import Vue from 'vue' import Vuex from 'vuex' //1 安装插件 Vue.use(Vuex) //2 创建对象 const store = new Vuex.Store({ state:{ count:1000 }, mutations:{ //方法 increment(state){ state.count++ }, decrement(state){ state.count-- } }, actions:{ }, getters:{ }, modules:{ } }) //3 导出store对象 export default store 让所有vue组件都可以使用这个store对象,我们需要在main.js中导入store对象,并且放在new Vue中,这样在其他组件里就可以通过this.$store的方式获取这个store对象了。 //main.js import Vue from 'vue' import App from './App' import store from './store' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', store, render: h => h(App) }) 使用vuex的count * 通过this.$store.state属性的方法来访问状态 * 通过this.$store.commit(‘mutation中的方法’)来修改状态注意:我们是通过提交mutation的方式,而非直接改变this.$store.state.count,这样Vuex可以更加明确地追踪状态的改变,不要直接改变this.$store.state.count的值。 //App.vue <template> <div id="app"> <h2>---------App内容---------</h2> <h2>{{$store.state.count}}</h2> <button @click="addition">+</button> <button @click="substraction">-</button> <!-- <hello-vuex :count="count"></hello-vuex> --> <h2>---------Hello Vuex内容--------</h2> <hello-vuex/> </div> </template> <script> import HelloVuex from './components/HelloVuex' export default { name: 'App', data() { return { message:'我是app组件', // count:0 } }, components: { HelloVuex }, methods: { addition(){ this.$store.commit('increment') //传入mutation中定义的方法名字 }, substraction(){ this.$store.commit('decrement') } }, } </script> <style> </style>

    04. vue五个核心

    1. state单一状态树(Single Source of Truth 单一数据源)

    在开发中,如果状态信息是保存到多个store中的,那么之后的管理和维护等等都会变得比较困难,因此Vuex使用了单一状态树来管理应用层级的全部状态。单一状态树能够让我们以最直接的方式找到某个状态的片段,而且在之后的维护和调试过程中,也可以非常方便地管理和维护。

    2. Getters

    Getters的基本使用 //store/index.js const store = new Vuex.Store({ state:{ count:1000, students:[ {id:110,name:'why',age:18}, {id:111,name:'coco',age:20}, {id:112,name:'lolo',age:21}, {id:113,name:'hsh',age:24}, ] }, mutations:{...}, actions:{}, //从store拿某个数据,这个数据需要经过某种变化之后再返回,我们都可以给它定义一个getters getters:{ //当对属性的输出需要做一些处理时,可以使用getters,就像计算属性一样 powerCounter(state){ return state.count * state.count //获取平方 }, more20stu(state){ return state.students.filter(s => s.age>20) } }, modules:{} }) //App.vue --- 需要经过处理展示的数据都可以在state中的getters变化后获取 <h2>---------App内容,演示getters相关信息---------</h2> <!-- <h2>{{$store.state.count * $store.state.count}}</h2> --> <h2>{{$store.getters.powerCounter}}</h2> <!-- <h2>{{more20stu}}</h2> 使用自己的计算属性 --> <h2>{{$store.getters.more20stu}}</h2> 不要直接在App.vue中定义计算属性来处理数据,因为这仅仅对App.vue一个页面有效。 // computed: { // more20stu(){ //使用计算属性,拿到state中的students进行过滤,但是这样写,每一个界面都需要添加一样的计算属性代码 // return this.$store.state.students.filter(s=>{ // return s.age > 20 //可以直接省略{}和return // }) // } // }, getters作为参数和传递参数 getters:{ ... //02 getters作为参数传入可以方便我们拿到getters中其他数据 more20stuLength(state,getters){ // return state.students.filter(s => s.age>20).length return getters.more20stu.length }, //03 getters传递参数 moreAgeStu(state){ return function(age){ //返回一个函数给别人调用 return state.students.filter(s => s.age>age) } // return age => { // return state.students.filter(s => s.age>age) // } } }, //App.vue <!-- <h2>{{$store.getters.more20stu.length}}</h2> --> <h2>{{$store.getters.more20stuLength}}</h2> <!-- 当getters需要传参数,getter中的moreAgeStu本身是返回一个函数的--> <h2>{{$store.getters.moreAgeStu(21)}}</h2>

    3. mutations

    Vuex的store状态的更新唯一方式:提交MutationMutation主要包括两个部分: 字符串的事件类型(type) 一个回调函数(handler),该回调函数的第一个参数就是state mutations传递参数 在通过mutation更新数据的时候,有时候希望携带一些额外的参数,这些参数被称为mutation的载荷(Payload) mutations:{ //方法 ... incrementCount(state,count){ state.count += count }, addStudent(state,stu){ state.students.push(stu) } }, //app.vue <button @click="addCount(5)">+5</button> <button @click="addCount(10)">+10</button> <button @click="addStudent">添加学生</button> ... methods: { ... addCount(count){ this.$store.commit('incrementCount',count) //提交的时候,携带参数提交过去 }, addStudent(){ const stu = {id:114,name:'ami',age:25} //参数较多时,可以搞成一个对象 this.$store.commit('addStudent',stu) } }, mutations提交风格 上面通过commit提交是一种普通的方式,Vue还提供了另外一种风格,它是一个包含type属性的对象。 //App.vue addCount(count){ //1 普通的提交风格 // this.$store.commit('incrementCount',count) //提交的时候,携带参数提交过去 //2 特殊的提交风格 this.$store.commit({ type:'incrementCount', count:count }) }, //index.js --- mutations incrementCount(state,payload){ //当使用特殊的提交风格时,payload只是一个名称,代表我们commit的整个对象 // console.log(count); {type: "incrementCount", count: 10} state.count += payload.count }, vuex响应式原理 state中定义的数据,它们的属性都会加入到响应式系统中,而响应式系统会监听属性的变化,当属性发生变化时,会通知所有界面中用到该属性的地方,让界面发生刷新。 我们必须遵守Vuex对应的规则: 提前在store中初始化好所需的属性当给state中的对象添加新属性时,使用下面的方式: 方式一:使用Vue.set(obj,‘newProp’,1) 方式二:用新对象给旧对象重新赋值 updateInfo(state){ state.info.name='codewhy' //改变属性 //添加属性 // state.info['address'] = '洛杉矶' 非响应式 Vue.set(state.info,'address','洛杉矶') //将该属性也添加到响应式系统 //删除属性 // delete state.info.age 该方法也不是响应式 Vue.delete(state.info,'age') } mutations的类型常量 在mutation中,我们定义了很多事件类型(也就是其中的方法名称),当方法越来越多的时候,我们在多个文件之间来回切换,可能会写错方法的名字,所以我们最好把方法的名字抽取成常量。 //mutations-types.js 我们可以把mutations中的方法类型全部在这里抽取成常量 export const INCREMENT = 'increment' //mutations中我们直接这样定义方法 mutations:{ //方法 [INCREMENT](state){ state.count++ }, ... } //App.vue //在需要提交方法的地方,我们也以这个常量代替方法名 methods: { addition(){ this.$store.commit(INCREMENT) //传入mutation中定义的方法名字 }, ... }

    3. vuex-actions

    通常情况下,Vuex要求我们Mutations中的方法必须是同步方法,主要原因是当我们使用devtools时,可以devtools可以帮助我们捕捉mutation的快照。但是如果是异步操作,那么devtools将不能很好地追踪这个操作什么时候会被完成。Action类似于Mutation,是用来代替mutation进行异步操作的。 虽然这样写看上去有点多余,但是却是必要的,这样我们的devtools就可以跟踪到修改了,并且在actions中也是可以传递参数或函数的。 mutations:{ ... updateInfo(state){ state.info.name='codewhy' //改变属性 //错误代码,不能在这里进行异步操作,devtools无法跟踪 // setTimeout(()=>{ // state.info.name='codewhy' // },1000) } }, actions:{ //context上下文 aUpdateInfo(context,payload){ //payload接收参数 //异步操作 setTimeout(()=>{ // context.state.info.name = 'codewhy' 修改state只能在mutaions中,不要直接改! context.commit('updateInfo') console.log(payload); //打印传递过来的参数 },1000) -------------------------------------- setTimeout(()=>{ context.commit('updateInfo') payload() //提交后回调这个函数通知外面已经完成了 },1000) -------------------------------------- setTimeout(()=>{ context.commit('updateInfo') console.log(payload.message) //打印参数 payload.success() //回调函数 },1000) } }, //App.vue updateInfo(){ // this.$store.commit('updateInfo') --- commit是提交到mutations //异步操作需要经过actions //01 传递参数 this.$store.dispatch('aUpdateInfo','我是传递来的参数') -------------------------------------- //02 传递一个函数 this.$store.dispatch('aUpdateInfo',()=>{ console.log('里面已经完成了'); }) -------------------------------------- //03 既传递参数又传递函数 this.$store.dispatch('aUpdateInfo',{ message:'我是携带的信息', success:()=>{ console.log('里面已经完成了'); } }) } 更优雅的写法: actions中方法本身可以返回一个Promise,我们可以在另一个地方dispatch拿到这个Promise,在后面写then方法,就可以继续使用这个Promise了。 //index.js actions:{ aUpdateInfo(context,payload){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ context.commit('updateInfo') console.log(payload); //打印传递的参数 resolve('1111111') //提交完毕后会执行这里的代码 },1000) }) } }, //App.vue updateInfo(){ //使用dispatch,而aUpdateInfo定义了Promisse,所以返回的promise可以在这里用,内部可以告诉外部一些信息 this.$store.dispatch('aUpdateInfo','我是携带的信息').then(res=>{ console.log('里面已经完成了提交'); //提示 console.log(res); }) }

    4. vuex-modules

    认识module(模块) Vue使用单一状态树,那么意味着很多状态都会交给Vuex来管理,当应用变得非常复杂时,store对象就有可能变得相当臃肿,为了解决这个问题,Vuex允许我们将store分割成模块,而每个模块拥有自己的state、mutations、actions、getters等 用法和之前是差不多的: //index.js const moduleA = { state:{ name:'lisa' }, mutations:{ updatedName(state,payload) { //不要起重复的名字,否则提交可能会错误 state.name = payload }, }, getters:{ fullname(state){ return state.name + '1111' }, fullname2(state,getters){ return getters.fullname + '2222' }, fullname3(state,getters,rootState){ //在模块中可以有第三个参数,拿到根的state return getters.fullname2 + rootState.count } }, actions:{ aUpdateName(context){ setTimeout(()=>{ context.commit('updatedName','wangwu') //只commit自己的mutations },1000) } }, } const store = new Vuex.Store({ ... modules:{ a: moduleA //这个a会被放入state中 } }) //App.vue <h2>---------App内容,modules中的内容---------</h2> //a是放在state中的 <h2>{{$store.state.a.name}}</h2> //提交到mutation的方法 <button @click="updateName">修改名字</button> //getters <h2>{{$store.getters.fullname}}</h2> <h2>{{$store.getters.fullname2}}</h2> <h2>{{$store.getters.fullname3}}</h2> //异步 <button @click="asyncUpdateName">异步修改名字</button> ... updateName(){ this.$store.commit('updatedName','jenny') //直接commit,只要方法名不重复一般不会错 }, asyncUpdateName(){ this.$store.dispatch('aUpdateName') } vue-store文件夹的目录结构 除了state(没必要)之外,其他各个核心的代码都可以单独抽出来,方便管理。 import Vue from 'vue' import Vuex from 'vuex' import mutations from './mutations' import actions from './actions' import getters from './getters' import moduleA from './modules/moduleA' //1 安装插件 Vue.use(Vuex) //2 创建对象 const state = { //数据都是响应式的 count:1000, students:[ {id:110,name:'why',age:18}, {id:111,name:'coco',age:20}, {id:112,name:'lolo',age:21}, {id:113,name:'hsh',age:24}, ], info:{ name:'kobi', age:40, height:1.88 } } const store = new Vuex.Store({ state:state, mutations:mutations, actions:actions, //从store拿某个数据,这个数据需要经过某种变化之后再返回,我们都可以给它定义一个getters getters:getters, modules:{ a: moduleA //这个a会被放入state中 } }) //3 导出store对象 export default store

    三. axios

    01 axios框架的基本使用

    1.安装axios框架 安装时出bug:代理有问题 找了一篇关于解决的博客:参考 还是不会安装,所以我尝试了另一个:cnpm 查了一下版本之后,居然就可以安装了,可能还是npm没反应过来吧。

    使用axios import Vue from 'vue' import App from './App' import axios from 'axios' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', render: h => h(App) }) //axios支持Promise axios({ url:'http://123.207.32.32:8000/home/multidata', //只传url默认是get请求 // method:'POST' method:'GET' //指定请求方式,该接口暂时不支持post }).then(res => { console.log(res); }) axios({ url:'http://123.207.32.32:8000/home/data', //可以直接跟参数?type=sell&page=3,或者下面单独写在params中 //专门针对get请求的参数拼接 params:{ type:'pop', page:1 } }).then(res => { console.log(res); })

    02 axios发送并发请求

    //使用全局的axios和对应的配置在进行网络请求 //2.axios发送并发请求 -- 对传入的多个网络请求进行合并 axios.all([ axios({ url:'http://123.207.32.32:8000/home/multidata', }), axios({ url:'http://123.207.32.32:8000/home/data', params:{ type:'sell', page:5 } }) ]).then(axios.spread((res1,res2) => { //axios.add([])返回的结果是一个数组,使用axios.spread可将数组[res1,res2]展开为res1,res2 console.log(res1); console.log(res2); })) // results => { //两个网络请求都完成后进行处理 // console.log(results); // } 补充知识: //对象的解构 const obj = { name:'kobi', age:30 } const {name,age} = obj //数组的解构 const names = ['why','are','you'] const [name1,name2,name3] = names

    03 axios的配置信息相关

    //3.axios的全局配置 -- 公共 axios.defaults.baseURL = 'http://123.207.32.32:8000' axios.defaults.timeout = 5000 //设置超时 axios.all([ axios({ url:'/home/multidata', //只需要写不是公共部分的url }), axios({ url:'/home/data', ... }) ]).then(...)

    04 axios的实例和模块封装

    axios的实例 当项目变得复杂,接口的服务器不一定只有一个,这时我们使用全局配置的baseURL不满足需求,所以我们一般不会直接使用全局,而是创建一个实例,而且实例一般会有多个。 //创建对应的axios的实例 const instance1 = axios.create({ baseURL:'http://123.207.32.32:8000', timeout:5000 }) //使用实例 instance1({ url:'/home/multidata' }).then(res => { console.log(res); }) instance1({ url:'/home/data', params:{ type:'pop', page:1 } }).then(res => { console.log(res); }) //每个实例有自己独立的配置 const instance2 = axios.create({ baseURL:'http://111.222.32.32:8000', timeout:10000, headers:{} }) axios的模块封装 在使用第三方框架的时候,最好不要每个地方都引用,而是对它做一个封装,否则以后如果这个框架废弃或者出现问题时,更换框架会变得困难。 第一种封装: //----------- network/request.js ----------- //对axios做封装 import axios from 'axios' //1.传入配置以及两个回调函数 export function request(config,success,failure){ //1 创建axios实例 const instance = axios.create({ baseURL:'http://123.207.32.32:8000', timeout:5000 }) //发送真正的网络请求 instance(config) .then(res => { // console.log(res); success(res); //回调出去 }) .catch(err => { // console.log(err); failure(err); }) } //----------- mian.js ----------- //5.封装一个request模块 import {request} from './network/request'; request({ url:'/home/multidata' },res => { console.log(res); },err => { console.log(err); }) 第二种封装:但是这种也不是最终方案 //request.js //只传入一个参数,但是要求参数里必须传入回调函数 export function request(config){ //1 创建axios实例 const instance = axios.create({ baseURL:'http://123.207.32.32:8000', timeout:5000 }) //发送真正的网络请求 instance(config.baseConfig) .then(res => { config.success(res); //回调出去 }) .catch(err => { config.failure(err); }) } //main.js //把所有东西放到大的config中 request({ baseConfig:{ }, success:function(){ }, faliure:function(){ } }) 第三种封装:使用Promise //request.js export function request(config){ return new Promise((resolve,reject) => { //1 创建axios实例 const instance = axios.create({ baseURL:'http://123.207.32.32:8000', timeout:5000 }) //发送真正的网络请求 --- 这里进行异步操作 instance(config) .then(res => { resolve(res) }) .catch(err => { reject(err) }) }) } -------------最终:简化后----------------------- export function request(config){ const instance = axios.create({ //实例 baseURL:'http://123.207.32.32:8000', timeout:5000 }) //直接返回,instance本身就返回一个Promise --- 看源码 return instance(config) } // ------- main.js ------- //3. 继续调用Promise request({ url:'/home/multidata' }).then(res => { console.log(res); }).catch(err => { console.log(err); })

    05 axios拦截器的使用

    axios提供了拦截器,用于我们在发送每次请求或得到响应后,进行对应的处理。拦截请求或者响应之后还需要返回,否则信息被拦截,请求方获取不到。 export function request(config){ const instance = axios.create({ //实例 baseURL:'http://123.207.32.32:8000', timeout:5000 }) //2.axios的拦截器 // axios.interceptors 拦截全局 instance.interceptors.request.use(config => { //拦截请求 console.log(config); //2.1请求拦截的作用: //01 比如config中的一些信息不符合服务器的要求 //02 比如每次发送网络请求时,都希望在界面中显示一个显示的图标 //03 某些网络请求(比如登录token),必须携带一些特殊的信息 return config; //还得返回,否则config被拦截 },err => { console.log(err); }); instance.interceptors.response.use(res => { //拦截响应 // console.log(res); // res.data 过滤有用的信息 return res.data //处理完结果必须返回,否则请求拿不到结果 },err => { console.log(err); //Error: Request failed }); //直接返回,instance本身就返回一个Promise --- 看源码 return instance(config) }
    Processed: 0.015, SQL: 8