13.VUE vue-router路由编程式导航跳转Promise问题

417 阅读1分钟

vue-router 路由跳转两种形式

“声明式导航”和“编程式导航”

声明式导航:标签 router-link + to="路由页面"(相当于一个a标签)

export default new VueRouter({
    // 配置路由
    routes:[
        {
            path:"/home",
            component:Home,
            meta:{show:true}
        }
    ]
})
<router-link to="/home">
    <img src="./images/logo.png">
</router-link>

编程式导航:事件监听绑定函数,路由跳转时可执行传参等操作

export default new VueRouter({
    routes:[
        {
            path:"/search/:keyword?",  // +"?"代表params可传可不传(正则?:01)
            component:Search,
            meta:{show:true},
            name:"search"
        }
    ]
})
<button @click="goSearch">搜索</button>

<script>
export default {
    methods: {
        // 编程式导航:方法 $router.push() / $router.replace()
        goSearch() {
            // 路由传参:(params+query参数:params参数:属于路径当中的一部分,在配置路由的时候需要占位 path:"/search/:keyword"
            //                            query参数:不属于路径当中的一部分,类似于ajax中的queryString /home?k=v&kv= 不需要占位)
            // 第一种:字符串形式
            // this.$router.push("/search/" + this.keyword + "?k=" + this.keyword.toUpperCase())
            // 第二种:模板字符串形式
            // this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`)
            // 第三种:对象形式(需要给路由命名)
            this.$router.push({
                name: "search",
                params: { keyword: this.keyword },
                query: { k: this.keyword.toUpperCase() }
            })
        }
    }
}
</script>

为什么编程式导航进行路由跳转的时候,会出现警告错误?

最新的vue-router引入了Promise,路由标签 this.$router.push / replace 返回值为Promise对象,而Promise需要传入两个状态回调参数

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

解决方法1:添加回调参数

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

解决方法2:重写push/replace方法

import VueRouter from "vue-router";
Vue.use(VueRouter);
// 先把VueRouter原型对象的push, 先保存一份
let originPush = VueRouter.prototype.push;
// 重写push/replace
// 第一个参数:告诉原来push方法往哪里跳转(传递哪些参数)
// 第二个参数:成功回调
// 第三个参数:失败的回调
VueRouter.prototype.push = function(location, resolve, reject) {
  if(resolve && reject) {
    // this保证上下文为VueRouter类的实例而不是Window
    //call/apply区别
    //相同:都可以调用函数一次,都可以篡改函数的上下文一次
    //不同: call与apply传递参数: call传递参数用逗号隔开,apply方法执行传递数组
    originPush.call(this, location, resolve, reject);
  }else {
    originPush.call(
      this,
      location,
      () => {},
      () => {}
    );
  }
};