重写push与封装axios

384 阅读1分钟

一、重写push/replace方法

项目中vue编程式路由跳转到当前路由(参数不变),多次执行会抛出NavigationDuplicated的警告错误,声明式导航没有这种错误

1662997018434.png

为什么?
最新的vue-router引入promise,promise是需要成功与失败的回调的

let result =  this.$router.push({
        name:'search',
        params:{keyword: this.keyword },
        query:{k:this.keyword.toUpperCase()}
      })
      console.log(result)

1662998049755.png

分析

function push(){
    return new Promise((resolve,reject) =>{
    })
}

通过给push方法传递成功与失败的回调函数,可以捕获到当前信息,
所以,直接传2个空的就可以解决

this.$router.push({
        name:'search',
        params:{keyword: this.keyword },
        query:{k:this.keyword.toUpperCase()}
      }.() => {},(error)=>{console.log(error)})

1662998822438.png

分析

this:当前组件实例(VueComponent)
this.$router:当前实例的属性,属性值VueRouter类的一个实例,
当在入口文件注册路由的时候,给组件实例添加$router|$route属性
push:VueRouter类的一个实例

function VueRouter(){
}
//原型对象的方法
VueRouter.prototype.push = function() {
//函数上下文为VueRouter类的一个实例
}
let $router = new VueRouter();
$router.push(xxx)

this.$router.push({
        name:'search',
        params:{keyword: this.keyword },
        query:{k:this.keyword.toUpperCase()}
      },()=>{},()=>{});
       console.log(this)
       console.log(this.$router)
       console.log(this.$router.push)

1663000052440.png

重写push

route/index.js

// 先把VueRouter原型对象的push,先保存一份
let originPush = VueRouter.prototype.push
// 重写
VueRouter.prototype.push = function(location,resolve,reject){
    if(resolve && reject){
        // call|apply区别
        // 相同点:都可以篡改函数上下文(this)一次
        // 不同点:call传递的是参数,用逗号隔开,apply传递的是数组
        originPush.call(this,location,resolve,reject)
    }else {
        originPush.call(this,location,()=>{},()=>{})
    }
}

重写replace

let originReplace = VueRouter.prototype.replace;

VueRouter.prototype.replace = function(location,resolve,reject){
    if(resolve && reject){
        originReplace.call(this,location,resolve,reject)
    } else {
        originReplace.call(this,location,()=>{},()=>{})
    }
}

二、axios二次封装

请求拦截器:可以在发请求之前处理一些业务
响应拦截器:当服务器数据返回以后,可以处理一些事情

api/request.js

import axios from "axios";
import { config } from "vue/types/umd";
// 利用axios对象方法create,创建一个axios实例
const requests = axios.create({
    baseURL:'/api', //基础路径,发请求时,路径会出现api
    timeout:5000, //超时
});
// 请求拦截器
requests.interceptors.request.use((config) => {
    //config:配置对象,对象里面的一个属性很重要,headers请求头
    return config 
})
// 响应拦截器
requests.interceptors.response.use((res)=>{
    return res.data;
},()=> { //失败的回调
    return new Promise.reject(new Error("failed"))
})
// 向外暴露
export default requests;

参考:

www.bilibili.com/video/BV1Vf… (part:10、16)