25、Vuex
<body>
<script>
// Vuex
// 1、先看下Vuex的图
// 思考一下:Actions是不是很无聊,很多余,Actions内部不直接执行方法,而是利用commit
// 让方法在Mutations里面执行,到底多不多余呢
// 你想想,你去找actions执行事件,结果他来一句,你要干这个事,我和mutations说了,你去找他吧
// 那为什么不直接去找mutations呢
// 这个时候你好好看下图,actions链接了一个backend API,也就是后端接口
// 当你需要的值需要从后端取的时候,这个时候actions就起作用了,他支持异步,可以发ajax请求
// 他会把异步的结果返回给你然后再commit找mutations
// mutations才是真正管理state状态的人
// 2、安装Vuex
// 注意vue2只能装vuex的3版本
// vue3才能用vuex的4版本
// 如果vue2安装vuex的3版本的话,会报错,包冲突
// npm i vuex@3
// 3、使用Vuex
// 有一个注意点:脚手架里面写import的时候,比如在main.js里面
// 脚手架是先把所有import语句执行完之后再执行内部其他的语句的
// 所以我们不在main.js里Vue.use(Vuex),而是像下面这么做
// 在src文件下创建一个store文件夹,里面创建一个index.js文件
// 在文件里写这些
// **************************************************
import Vue from 'vue'
// 引入Vuex
import Vuex from 'vuex'
//准备actions:用于相应组件中的动作
const actions = {
jia(context, value) {
// 观察一下这两个参数是分别是什么
// params context: 一个上下文对象,先不要理解了,知道他又commit方法就行
// params value: 在组件里dispatch调用时传入的值
context.commit('JIA', value);
},
// 还可以做判断,当sum的值是奇数再加
// actions之所以支持异步,发送ajax请求,是因为
jiaOdd(context, value) {
// 也就是或这里面是可以执行很多逻辑的
// 执行完最后再去调用commit
if(context.state.sum % 2) {
context.commit('JIA', value);
}
}
}
//准备mutations:用于操作state中的数据
const mutations = {
JIA(state, value) {
state.sum += value;
}
}
//准备state:用于管理所有数据的
const state = {
sum: 0,
}
Vue.use(Vuex);
// 创建并暴露store
/* export default new Vuex.Store(
{
actions,
mutations,
state
}
) */
// **************************************************
// 在main.js里引入store并使用
import Vue from 'vue'
import App from './App.vue'
// 引入写好的store
import store from './store/index'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
store
}).$mount('#app');
</script>
<script>
// 4、在组件中使用
/* <h2>{{$store.state.sum}}</h2> */
// 在方法里怎么用
increment() {
this.$store.dispatch('jia', 2);
}
// 或者直接走commit,记住要写大写了,mutations里是大写
increment() {
this.$store.commit('JIA', 2);
}
</script>
<script>
// 5、Vuex的模块化写法
const countOptions = {
actions: {
jia(context, value) {
context.commit('JIA', value);
},
},
mutations: {
JIA(state, value) {
state.sum += value;
}
},
state: {
sum: 1
}
}
const peopleOptions = {
namespaced: true,
actions: {},
mutations: {},
state: {
people: 'jjwu27'
}
}
export default new Vuex.store(
{
modules: {
countOptions,
peopleOptions
}
}
)
// 6、在组件中使用
// 两种情况是否开启了namespaced: true,
// 开没开启namespaced,访问state中的变量都是一样的
/* <h2>{{$store.state.countOptions.sum}}</h2>
<h2>{{$store.state.peopleOptions.sum}}</h2> */
// 但是方法就不一样了,没开启namespaced: true,
increment() {
this.$store.dispatch('jia', 2);
}
// 或者直接走commit,记住要写大写了,mutations里是大写
increment() {
this.$store.commit('JIA', 2);
}
// 开启了namespaced: true之后,需要拼接路径
increment() {
this.$store.dispatch('countOptions/jia', 2);
}
// 或者直接走commit,记住要写大写了,mutations里是大写
increment() {
this.$store.commit('countOptions/JIA', 2);
}
</script>
<script>
// 7、actions中支持异步,我们写个请求接口的案例
// ********************************************
const actions = {
// 这里这个value其实用不上,我们要用的是请求过来的值,当然这只是一个例子
// 不是说这个value就用不上,要学会举一反三
addPersonServer(context,value) {
axios.get('https://api.uixsj.cn/hitokoto/get?type=social').then(
response => {
context.commit('JIA', {name: response.data})
},
error => {
}
)
}
}
// ********************************************
</script>
<script>
// 需要注意的点:
// 有没有发现在我的项目里都是直接在组件里调用的this.$store.commit,没有走this.$store.dispatch
// 这就是我们可以不找actions,可以直接找mutations
/* 项目里监听Vuex里的数据
@Watch('$store.state.common.delKlbResource', {
deep: true,
immediate: true
})
public watchDelKlbResource(newValue) {
} */
</script>
</body>
26、路由
<script>
// 路由
// 1、安装vue-router
// 也要注意vue-router4版本只能在vue3中用,所以我们要装vue-router3版本
// npm i vue-router@3
// 2、创建文件
// src下创建一个router文件夹,里面创建一个index.js文件
// 编写文件内容
// **********************************
import VueRouter from 'vue-router'
// 创建并暴露一个路由器
export default new VueRouter({
routes: [
{
path: '/father',
component: () => import('../components/Father.vue')
},
{
path: '/home',
component: () => import('../components/Uncle.vue')
}
]
})
// **********************************
// 3、引入并使用
// 在main.js中引入并使用
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import router from './router/index'
Vue.config.productionTip = false
Vue.use(VueRouter);
new Vue({
render: h => h(App),
store,
router
}).$mount('#app')
// 4、App中使用
/* <template>
<div id="app">
<router-link to="/father">Father</router-link>
<router-link to="/home">Uncle</router-link>
<router-view></router-view>
</div>
</template> */
// 需要注意的是每个组件都会有$route和$router, 每个组件的$route都是不一样的
// 但是他们呢的$router是一样的,因为这是一个总的路由器,整个应用只有一个router,通过$router获取
// 每个组件都有自己的$route属性,里面存储的是自己的路由信息
</script>
<script>
// 2、多级路由
// 在配置文件中写
import VueRouter from 'vue-router'
// 注意子路由不需要加斜杠/
export default new VueRouter({
routes: [
{
path: '/father',
component: () => import('../components/Father.vue'),
children: [
{
path: 'brother',
component: () => import('../components/Brother.vue')
},
{
path: 'sister',
component: () => import('../components/Sister.vue')
}
]
},
{
path: '/uncle',
component: () => import('../components/Uncle.vue'),
children: [
{
path: 'brother',
component: () => import('../components/Brother.vue')
},
{
path: 'sister',
component: () => import('../components/Sister.vue')
}
]
}
]
})
// 在组件里这么写
/* <template>
<div class="father">
<h2>我是爸爸</h2>
<router-link to="/father/brother">Father/Brother</router-link>
<br>
<router-link to="/father/sister">Father/Sister</router-link>
<router-view></router-view>
</div>
</template> */
</script>
<script>
// 3、路由传参
// 两种形式
// 第一种query形式的第一种写法
// 在router-link里这样写:用?和&符号连接参数
// <router-link to="/father/brother?id=123&name=jjwu27">Father/Brother</router-link>
// 路由组件里接收:this.$route.query
// 第一种query形式的第二种写法
// to绑定对象形式
// <router-link :to="{path: '/father/sister', query: {id: 12345, name:'hahahah'}}">Father/Sister</router-link>
// 接收是一样的
// 第二种params形式的写法
// 先改配置,给路由path后面追加占位符然后写上属性名,代表参数
export default new VueRouter({
routes: [
{
path: '/father',
component: () => import('../components/Father.vue'),
children: [
{
path: 'brother',
component: () => import('../components/Brother.vue')
},
{
path: 'sister',
component: () => import('../components/Sister.vue')
}
]
},
{
path: '/uncle',
component: () => import('../components/Uncle.vue'),
children: [
{
name: 'brother',
path: 'brother/:id/:title',
component: () => import('../components/Brother.vue')
},
{
name: 'sister',
path: 'sister/:params',
component: () => import('../components/Sister.vue')
}
]
}
]
})
// 在router-link里这样写,router会识别出来从哪里开始是参数
// <router-link to="/father/brother/123/加油">Father/Brother</router-link>
// 路由组件里接收:this.$route.params
// 第二种形式的第二种写法
// 注意的是:当使用这种写法时,不可以配置path,而是必须写name的写法
// <router-link :to="{name: 'sister', params: {id: 12345, name:'hahahah'}}">Father/Sister</router-link>
// 路由路径的简写形式
// 首先配置路由的时候给到name属性
// **********************************
// 创建并暴露一个路由器
/* export default new VueRouter({
routes: [
{
path: '/father',
component: () => import('../components/Father.vue'),
children: [
{
path: 'brother',
component: () => import('../components/Brother.vue')
},
{
path: 'sister',
component: () => import('../components/Sister.vue')
}
]
},
{
path: '/uncle',
component: () => import('../components/Uncle.vue'),
children: [
{
name: 'brother',
path: 'brother',
component: () => import('../components/Brother.vue')
},
{
name: 'sister',
path: 'sister',
component: () => import('../components/Sister.vue')
}
]
}
]
}) */
// router-link里这么写就好了
// <router-link :to="{name: 'brother'}">Father/Brother</router-link>
// <router-link :to="{name: 'sister', query: {id: 12345, name:'hahahah'}}">Father/Sister</router-link>
// 注意以及路由不许这样写,只有多级路由才可以简化
</script>
<script>
// 4、浏览器的历史记录(这块具体可以看尚硅谷125集)
// 路由支持浏览器的前进后退,采用的是push模式,压栈和出栈的模式
// 这样就有了前进和后退就是路由的压栈出栈
// replace模式,给router-link标签添加replace,这个是替换当前记录,这个就没有前进后退模式
// <router-link replace to="/father">Father</router-link>
// 注意:路由跳转默认采用的是push模式
// 一般我们搭配使用,大部分路由支持前进后退,有的你不想支持前进后退就给router-link开启replace属性
</script>
<script>
// 5、编程式路由导航
// 不用router-link,通过点击事件跳转路由
/* <button @click="jump"></button> */
// 注意这里用的是$router,配置项可以写name也可以写path
jump() {
this.$router.push({
name: 'sisiter',
query: {
id: 123,
name: 'jjwu27'
}
})
}
// 前进写法:
forward() {
this.$router.forward();
}
// 后退写法
back() {
this.$router.back();
}
// go的作用
go() {
this.$router.go(-2);// 后退两步
this.$router.go(-2);// 前进两步
}
</script>
<script>
// 6、缓存路由组件
// 用keep-alive组件包裹,包裹的所有内容支持保持原状态
// 当然也可以选择保留那些组件的状态,用include
// 这里的News、Message是组件名!组件名!组件名!!!,代表只保留News、Message组件的状态
/* <keep-alive :include="['News', 'Message']">
<router-view></router-view>
</keep-alive> */
// 7、路由组件独有的两个声明周期钩子
// 激活
activated() {
//路由组件被激活也就是出现时调的钩子
}
// 失活
deactivated() {
// 路由组件消失的时候调用的钩子,注意这里用的是消失,不是销毁
// 其实这两个钩子在路由组件里可以用来代替mounted和beforeDestroy
// 应用场景就是我们上面说的那个缓存路由组件的时候,组件没有被销毁,
// 组件消失是不会调用beforeDestroy钩子的,下一次打开也不会调用
// munted钩子,这个时候activated和deactivated钩子就会起到作用
}
</script>
<script>
// 7、路由守卫:很重要(路由的权限问题)
// 7.1、进入路由前的校验:前置路由守卫
// 想做校验,不能直接创建路由配置了,要这样写
// 我们在创建好一个router对象的时候不直接暴露
const router = new VueRouter({
routes: [
{
name: 'father',
path: '/father',
component: () => import('../components/Father.vue'),
children: [],
meta: { // 路由元信息,程序员自定义的信息
isAuth: true, //我在这里配置了一个isAuth字段,用于鉴别这个路由是否开启访问权限
title: '父亲'
}
},
{
name: 'uncle',
path: '/uncle',
component: () => import('../components/Uncle.vue'),
children: [],
meta: {
isAuth: true,
title: '叔叔'
}
}
]
})
//然后做全局前置路由守卫: 初始化的时候调用以及每次路由切换前被调用
router.beforeEach((to, from, next) => {
console.log(to,from);
next() //next是放行,你必须写这个它才会继续走,不然代码会被打断
})
// 有了next我们就可以做守卫了呀
router.beforeEach((to, from, next) => {
if (to.path === '/home/news') {
if (localStorage.getItem('name') === 'jjwu27') {
next(); // 这样就只有jjwu27可以进入到home下的news啦
} else {
alert('您没有权限进入哦!')
}
} else {
next();
}
})
// 搭配我们写的isAuth字段使用,一种规范的写法
router.beforeEach((to, from, next) => {
if (to.meta.isAuth) {
if (localStorage.getItem('name') === 'jjwu27') {
next(); // 这样就只有jjwu27可以进入到father路由哦
} else {
alert('您没有权限进入哦!')
}
} else {
next();
}
})
// 7.2、后置路由守卫:初始化的时候被调用,每次切换路由后被调用
router.afteEach((to, from) => {
// 这里的to和from和前置是一样的都是从哪到哪
// 后置路由守卫到底守卫什么呢
// 有这么一个效果document.title可以改变页面的标题信息
// 那我们呢就是让每次跳转到那个页面就把标题改为这个页面
// 这个用前置守卫怎么实现都不完美,但是后置路由就很完美
document.title = to.meta.title || '没有值就显示我'
})
// 7.3、独享路由守卫:写在路由的配置文件里
// 独享路由守卫只有前置守卫
// 前置路由守卫和独享路由守卫是可以搭配使用的
const router2 = new VueRouter({
routes: [
{
name: 'father',
path: '/father',
component: () => import('../components/Father.vue'),
children: [],
meta: {
isAuth: true, //我在这里配置了一个isAuth字段,用于鉴别这个路由是否开启访问权限
title: '父亲'
}
},
{
name: 'uncle',
path: '/uncle',
component: () => import('../components/Uncle.vue'),
children: [],
meta: {
isAuth: true,
title: '叔叔'
}
},
{
name: 'message',
path: '/message',
component: () => import('../components/Message.vue'),
children: [],
meta: { // 路由元信息,程序员自定义的信息
isAuth: true,
title: '私密信息'
},
beforeEnter: (to, from, next) => {
if (to.meta.isAuth) {
if (localStorage.getItem('name') === 'jjwu27') {
next();
} else {
alert('您没有权限进入哦!')
}
} else {
next();
}
}
}
]
})
// 7.4、组件内路由守卫
// 这个要进入到组件里面,前提是你的组件是配置过的路由组件
// 组件里这么写
// ****************************************************
<template>
<h2>我是路由组件哦</h2>
</template>
<script>
export default {
name: 'App',
mounted() {
},
// 通过路由规则,什么叫通过路由规则进入呢,就是走router-view进入该组件时被调用,普通的组件注册调用是不起作用的
/* beforeRouteEnter(to, from, next) {
if (to.meta.isAuth) {
if (localStorage.getItem('name') === 'jjwu27') {
next(); // 这样就只有jjwu27可以进入到father路由哦
} else {
alert('您没有权限进入哦!')
}
} else {
next();
}
}, */
// 通过路由规则,离开该组件时被调用
beforeRouteLeave(to, from, next) {
}
}
</script>
// ****************************************************
// 总结!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// 路由守卫的执行顺序:beforeEach => beforeEnter => beforeRouteEnter => afterEach
</script>
27、路由的两种工作模式hash和history
<script>
// 路由的两种工作模式
// 1、默认开启的是hash模式:标志是#
// 2、第二种是history模式
// 怎么修改配置呢??,配置文件里改
const router = new VueRouter({
mode: 'history',
routes: [
{
}
]
})
// 什么是hash值:#及后面的内容就是hash值
// hash值不会包含在HTTP请求中,即hash不会带给服务器
// 对比一下
// hash的兼容性略好点; hash的路径里有#符号,不是很美观
// hash模式不会把#后面的内容当作请求路径,但是history会,history会根据的你网址路径去找对应路径的文件
// 由于history的路径会参与http请求,所以用history的时候,部署上线的时候需要后端人员支持,解决刷新页面服务端404的问题
</script>
28、Promise
<script>
// Promise
// 什么时候用到:一般是有异步操作时,用promise对异步操作做封装
// 1、认识promise
new Promise((resolve, reject) => {
// 这里假设定时器是异步请求,假设网络请求成功了,res是返回数据,拿到数据后
// 我们调用成功的回调,resolve参数,他也是个函数,他会携带res直接跑到then方法里
// 如果失败了,就调用reject,然后携带错误信息跳转到catch方法里
// 模拟这是成功的回调
setTimeout(res => {
resolve()
}, 1000)
// 模拟这是失败的回调
setTimeout(err => {
reject(err)
}, 1000)
}).then(res => {
}).catch(arr => {
})
// 另一种写法,没有catch,而是then方法里有两个参数
new Promise((resolve, reject) => {
setTimeout(res => {
resolve()
}, 1000)
setTimeout(err => {
reject(err)
}, 1000)
}).then(res => {
}, err => {
})
// 2、promise的三种状态
// 首先要触发,怎么触发,当我们开发中有异步操作的时候,就可以给异步操作包装一个Promise
// 异步操作后又三种状态:
// pending:等待状态,比如正在进行网络请求,或者定时器没有到事件,创建promise对象,并且没有调用resolve和reject的时候
// fulfill:满足状态,当我们回调了resolve时,切换到该状态,并且会回调then()
// reject: 拒绝状态,当我们回调了reject时,切换到该状态,并且会回调catch()
// 3、promise的链式调用
// 为什么promise可以链式调用
// 因为then和catch方法的返回值都是promise对象呀!!!!
// 链式调用的步骤如下
new Promise((resolve, reject) => {
setTimeout(res => {
resolve(res)
}, 1000)
setTimeout(err => {
reject(err)
}, 1000)
}).then(res => {
// 处理代码
return new Promise((resolve, reject) => {
setTimeout(ans => {
resolve(ans)
}, 1000)
})
}).then(ans => {
// 处理代码
})
// 上面的代码还可以简写哦
new Promise((resolve, reject) => {
setTimeout(res => {
resolve(res)
}, 1000)
setTimeout(err => {
reject(err)
}, 1000)
}).then(res => {
// 处理代码
// 可以直接用Promsie点resolve这个方法,也会跳转到then方法里
return Promise.resolve(res + '111')
}).then(res => {
// 这里的res就是上面的res+111
// 处理代码
})
// 上面的方法还能继续简写哦
new Promise((resolve, reject) => {
setTimeout(res => {
resolve(res)
}, 1000)
setTimeout(err => {
reject(err)
}, 1000)
}).then(res => {
// 处理代码
// 可以直接返回结果,因为底层会为你自动包装一层Promsie
return res + '111'
}).then(res => {
// 这里的res就是上面的res+111
// 处理代码
})
// 注意!!!!!!!!!!!!!!!!!!!!
// 我们可以链式无限调用.then方法
// 会直接穿透到最后的catch方法里
// 4、Promise.all,同时处理多个请求结果
// 比如一个功能依赖两个请求
Promise.all([
new Promise((resolve,reject) => {
setTimeout((res1) => {
// 假装请求
resolve(res1)
}, 1000)
}),
new Promise((resolve,reject) => {
setTimeout((res2) => {
// 假装请求
resolve(res2)
}, 1000)
}),
]).then(results => {
// 这里的results就是一个数组
console.log(results[0]); // 第一个返回结果
console.log(results[0]); // 第二个返回结果
})
</script>
// 看一个案例:来自项目,只看promise就好了
public async addWordFromLeftBar(id) {
const currentContent = this.getCurrentInfo[0]
if (currentContent) {
const resource = currentContent?.properties?.find(i => i.name === 'resourceStatus')
if (resource && ['processing', 'init'].includes(resource.value)) {
await this.autoTempSave(deepClone(currentContent), this.getRealCurrentIndex())
}
}
const defaultProperties = JSON.parse(JSON.stringify(this.stbProperties));
delete defaultProperties.identifier;
delete defaultProperties.taskStatus;
delete defaultProperties.quantityCompleted;
delete defaultProperties.quantity;
delete defaultProperties.extendedInformation;
delete defaultProperties.completeTheResource;
const wordObj = deepClone(defaultProperties)
// 单词状态添加的默认为初始化待制作,不能继承
wordObj.resourceStatus = 'init'
delete wordObj.semester
delete wordObj.quantity
// 请求之前需要把年份的时间格式转换回来
wordObj.year = (new Date(wordObj.year)).getTime();
defaultProperties.year = (new Date(defaultProperties.year)).getTime();
const params = {
id: this.id,
label: 'package',
identifier: (this.stbProperties as any).identifier,
properties: defaultProperties,
imageVertexEntitys: [{
edgeLabel: 'produceWords',
generateQuantity: 1,
vertexEntity: {
label: 'dcsy',
properties: {
...wordObj,
name: ' '
}
}
}
]
}
this.$store.commit('setAppSpinShow', true);
addDcEntity(params).then(res => {
this.$Message.success('添加单词成功')
}).catch(() => {
this.$Message.error('添加单词失败')
}).finally(() => {
this.$store.commit('setAppSpinShow', false);
})
}
29、axios
<script>
// axios
// 1、简单写法:基本使用
// 如果不写method,那么axios默认是get请求
axios({
url: 'http://baidu.com',
method: 'post'
}).then(res => {
console.log(res);
})
// 也可以这样写:axios有很多内置的方法,每一种请求方式都可以直接点
// 具体配置怎么写自己可以在用的时候查看一下
axios.get(url).then(res => {})
// 2、axios处理多个请求
axios.all([
axios({
url: 'http://baidu.com',
method: 'post'
}),
axios({
url: 'http://baidu.com',
method: 'post'
})
]).then(results => {
// 这里的results就是一个数组
// 数组的每一项就是请求结果
})
// 注意axios为我们提供了一个展开数组结果的方法哦
axios.all([
axios({
baseURL: 'http://baidu.com',
timeout: 5,
url: '/home',
method: 'post'
}),
axios({
baseURL: 'http://baidu.com',
timeout: 5,
url: '/family',
method: 'post'
})
]).then(axios.spread((res1, res2) => {
console.log(res1),
console.log(res2)
}))
//当然我觉得用数组的解构更方便
// 3、全局配置
// 对比一下上面的baseURL和 timeout我们就可以写成全局配置
axios.defaults.baseURL = 'http://baidu.com';
axios.defaults.timeout = 5000;
axios.all([
axios({
url: '/home',
method: 'post'
}),
axios({
url: '/family',
method: 'post'
})
]).then(([res1, res2]) => {
console.log(res1, res2)
})
// 4、axios的实例
// 这样每一个实例对象都可以写自己的默认配置
const instance1 = axios.create({
baseURL: 'http://baidu.com',
timeout: 5000
})
instance1({
url: '/home'
}).then(res => {
})
instance1({
url: '/family'
}).then(res => {
})
// 再创建一个实例
const instance2 = axios.create({
baseURL: 'http://junjie.fun',
timeout: 5000
})
instance2({
url: '/home'
}).then(res => {
})
instance2({
url: '/family'
}).then(res => {
})
// 5、封装axios用于项目
export function request(config) {
// 第一种写法
/* return new Promsie((resolve, reject) => {
// 创建axios实例
const instance = axios.create({
baseURL: 'http://junjie.fun',
timeout: 5000
})
// 发送网络请求
instance(config)
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
})
}) */
// 第二种写法
// axios创建的实例本身就是Promise对象,可以直接返回
const instance = axios.create({
baseURL: 'http://junjie.fun',
timeout: 5000
})
// 发送网络请求
return instance(config);
}
// 引入封装好的请求
import { request} from './jjwu27/request';
// 使用它
request({
url: '/home',
method: 'post'
}).then(res => {
}).catch(res => {
})
// 6、搭配拦截器使用
export function request(config) {
const instance = axios.create({
baseURL: 'http://junjie.fun',
timeout: 5000
})
// 添加拦截器
// 请求拦截器:两个回调,成功回调和失败回调
instance.interceptors.request.use(config => {
// 这里是请求成功触发的响应拦截
// 请求拦截主体(作用)
// ************************************************
// 比如处理config中的一些不符合要求的信息
// 处理请求头等信息
// 高频用法:发送网络请求的时候做遮罩层效果
// 登录失效提示:可以在这里做token信息的校验,如果没有的话,提示用户重新登录
// ************************************************
// 必须返回config
return config;
},
err => {
// 这里是请求失败触发
})
// 响应拦截器
// 两个回调和请求拦截一样
instance.interceptors.response.use(res => {
// 1、关闭遮罩层等
// 响应拦截后必须把值返回,否则接口的结果会被拦截
return res
},
err => {
})
// 发送网络请求
return instance(config);
}
// 引入封装好的请求
import { request } from './jjwu27/request';
// 使用它
request({
url: '/home',
method: 'post'
}).then(res => {
}).catch(res => {
})
</script>