vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】

时间:2022-11-06 01:12:47

vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】

8.路由跳转与传参相关面试题

面试题1:路由传递参数(对象写法),path是否可以结合params参数一起使用?

答案:不能,实际效果是输入内容点击搜索按钮,也无法跳转到搜索页,因为路由压根接收不到参数,测试代码如下

this.$router.push({path: '/search', params:{keyword:this.keyword}, query:{k:this.keyword.toUpperCase()}})

vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】

面试题2:如何指定params参数可传可不传?

答案:通过一个占位符问号’?'进行控制,举例说明代码

//配置路由
export default new VueRouter({
    routes:[       
        {
            path: '/search/:keyword?',
            component: Search,
            meta:{"isShow": true}
        }
    ]
})

注意点1:人家要求传递params参数,但是我就不传,会出现的效果是URL会有问题,测试代码举例如下

this.$router.push({name: 'search', query:{k:this.keyword.toUpperCase()}})

页面效果如下,正确路径应该显示http://localhost:8080/?#/search/qwe?k=QWE,而现在错误显示http://localhost:8080/?#/?k=QWE,明显少了/search,这种可能后续开发就容易引起其他不便于排查的问题,所以至少要保证URL是没问题的才能继续开发。

vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】

面试题3:params参数可以传递也可以不传递,但是如果传递是空串,如何解决?

答案:

解决1: 不指定params

解决2: 指定params参数值为undefined

使用underfined解决,params参数可以传递,不传递(空字符串),正确写法如下:params:{keyword:‘’ || underfined}

this.$router.push({name: 'search', params:{keyword:'' || underfined}, query:{k:this.keyword.toUpperCase()}})

测试举例,我假设就传空字符串页面效果又是啥?

代码如下:

this.$router.push({name: 'search', params:{keyword:''}, query:{k:this.keyword.toUpperCase()}})

页面效果如下:你会发现/search仍然没了,跟上面的问题效果一样,导致的URL错误了

vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】

而使用正确写法后的效果如下:

vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】

面试题4:路由组件能不能传递props数据?

答案:是可以的,且有3种写法:布尔值形式、对象形式、函数形式

详情使用请看博客:https://blog.csdn.net/a924382407/article/details/125690420

面试题5:编程式路由跳转到当前路由(参数不变),多次执行会抛出NavigationDuplicated的警告错误?

效果演示如图,当连续多次点击搜索按钮时就开始报错了:

vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】

原因:我们知道路由跳转有2种形式:声明式导航、编程式导航,其中声明式导航没有这类问题,因为vue-router底层引入了promise且已经处理好了所以不会报错,然而编程式导航却没有做相应处理所以就导致了报错。

解决方案

解决1: 在跳转时指定成功或失败的回调函数, 通过catch处理错误

解决2: 修正Vue原型上的push和replace方法 (优秀)

实际的“编程式导航”是有返回值的,返回一个叫promise的对象,我们只需要通过push方法传递相应的成功、失败的回调函数,就可以捕获到当前错误,即可解决。

测试案例的报错代码如下:

goSearch() {      
      this.$router.push({name: 'search', params:{keyword:this.keyword}, query:{k:this.keyword.toUpperCase()}})
}

正确的完善代码如下:

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

注意:这种写法还是治标不治本,将来在别的组件当中使用push|replace时,总不能挨个写一堆,()=>{},()=>{} 这个吧。

所以要想治标治本先得了解这个push|replace是谁的方法,我们只需要重写这两个方法不就解决问题了。经过测试控制台打印输出了解到这个push|replace方法是VueRouter原型实例对象上的方法,所以在router文件夹下的index.js中重写方法即可。

//引入vue-router路由插件
import VueRouter from "vue-router";
//引入Vue
import Vue from "vue";
Vue.use(VueRouter);

//引入路由组件
import Register from '@/pages/Register'
import Login from '@/pages/Login'
import Home from '@/pages/Home'
import Search from '@/pages/Search'

//先把VueRouter原型对象的push方法,拷贝一份
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;
//重写push|replace方法,其中第1个参数告诉原来push方法,你往哪里跳转以及传递哪些参数,第2个参数代表成功回调,第3个参数代表失败回调
VueRouter.prototype.push = function (location, resolve, reject) {
    if (resolve || reject) {
        /**
         * call || apply 区别?
         * 相同点:都可以调用函数一次,都可以篡改函数的上下文一次
         * 不同点:call与apply传递参数中,call传递参数用逗号隔开,而apply传递数组
         */
        originPush.call(this, location, resolve, reject);
    } else {
        originPush.call(this, location, ()=>{}, ()=>{});
    }
}
VueRouter.prototype.replace = function (location, resolve, reject) {
    if (resolve || reject) {
        originReplace.call(this, location, resolve, reject);
    } else {
        originReplace.call(this, location, ()=>{}, ()=>{});
    }
}

//配置路由
export default new VueRouter({
    routes:[
        {
            path: '/home',
            component: Home,
            meta:{"isShow": true}
        },
        {
            name: 'search',
            //:keyword?    其中的?可以理解成正则中的问号,代表出现0次或1次,这样就能进行控制params参数传递与不传递
            path: '/search/:keyword?',
            component: Search,
            meta:{"isShow": true}
        },
        {
            path: '/register',
            component: Register,
            meta:{"isShow": false}
        },
        {
            path: '/login',
            component: Login,
            meta:{"isShow": false}
        },
        //重定向,在项目跑起来的时候,访问/,立马让他定向到首页
        {
            path: '*',
            redirect: "/home",
        }
    ]
})

面试题6: 跳转路由的2种基本方式

​ 声明式: <router-link to=“”>

​ 编程式: this.$router.push()/replace()

面试题7:跳转路由携带参数的2种方式

​ params参数

​ query参数

本人其他相关文章链接

1.vue尚品汇商城项目-day00【项目介绍:此项目是基于vue2的前台电商项目和后台管理系统】
2.vue尚品汇商城项目-day01【1.vue-cli脚手架初始化项目生成文件的介绍】
3.vue尚品汇商城项目-day01【2.vue-cli脚手架初始化项目的其他配置】
4.vue尚品汇商城项目-day01【3.项目路由的分析】
5.vue尚品汇商城项目-day01【4.完成非路由组件Header与Footer业务】
6.vue尚品汇商城项目-day01【5.路由组件的搭建】
7.vue尚品汇商城项目-day01【6.Footer组件的显示与隐藏】
8.vue尚品汇商城项目-day01【7.路由传参】
9.vue尚品汇商城项目-day01【8.路由跳转与传参相关面试题】