00:00
哈喽,各位小伙伴们大家好,那接下来啊,咱们呢,要去解决这样的一个问题,那么什么问题呢?就是编程式路由跳转到当前路由时啊,如果它传递的参数不变。多次执行呢,会抛出navigation duplicate这样的一个警告的错误。那有的小伙伴可能说老师是什么样的一个错误啊,咱们呢,可以看一下。就比如说啊,咱们目前而言是从home模块跳转到哪儿啊,是不是跳转到咱们的设置模块。对吧,那当然咱们呢,可以传递参数,比如说paramas参数或者是qua参数。比如说老师传递一个叫做q we OK,那咱们试一下。比如说当老师点击搜索按钮的时候,他会进行路由跳转,以及呢也会进行相应的传参,但是如果点击多次,那你会发现底下会有这样的一个警告的错误。
01:11
那咱们呢,得去聊聊。那首先说第一件事要注意,因为咱们的这个路由跳转啊,写一下就是路由跳转有两种形式。一种呢是声明式导航,那么另外一种呢,就是编程式导航。那当然啊,咱们在这个搜索按钮点击的时候,咱们是通过push进行跳转的,那么目前而言,咱们这块的业务逻辑所采用的呢,即为编程式导航。那这里呢,要注意一件事,就是刚刚看见的这样的一个警告错误啊,对于声明是导航是没有这类问题的。
02:01
为什么呢?哎,因为它的view-router,它的底层啊,已经处理好了。但是为什么咱们的编程式导航在进行路由跳转的时候就有这样的一个问题呢?对吧,那咱们呢,也去带一个小问题,就是为什么。编程式导航进行路由跳转的时候,哎,就有这种警告错误呢。那咱们呢,得去聊聊,首先说啊VE router啊,它最新版本的是3.5.3。他引入进来一个东西叫做promise啊,这块老师也做一下笔记。也就是说啊,最新的最新的VE告诉谁啊,Router它引入了什么呢?Promise。那咱们呢,可以先去看看啊,就比如说啊,找到咱们的组件,找到谁呢?找到这个hier,咱们可以看一下。
03:08
当点击搜索按钮的时候,OK,进行编程式导航,进行路由跳转。那你看一下子,那这块呢,是进行了,这是组建实例。调用了Dollar rooter这样的一个属性,以及调用了push方法,往哪push呢?往这个设置进行跳转以及穿参。那咱们呢,可以看一下子,也就是说push方法执行了一次,它是有返回结果的,那咱们呢,可以打印一下伪造的。对吧,那咱们看一下它有没有返回值cons,第2LOG,比如说啊,咱们打印一下子这个result。那咱们呢,去看一下子,你看啊,走老师的回手再测试一下,比如说咱就来个123,你看啊,当你一点击的时候,OK push方法一执行咋的,是不是返回了一个promise。
04:09
那么为什么会出现这样的一个警告或者是错误呢?就是因为promise他需要传递一个成功或者是失败的回调,那这样才能处理处理掉这次异常。所以说解决它呢,其实最好的办法呀,就是给他底层的,其实这个push方法可以怎么理解呢?你看咱们可以这么理解。就比如说啊,他们有一个函数叫做function对吧,比如说叫做什么叫做push。当然它返回的是什么呢?返回的是一个promise。对不,那么对于promise啊,咱们应该知道它是有成功与失败的回调,对吧,比如说是成功reject失败。这就是为什么咱们push的时候会返回一个promise。
05:02
那么为什么会爆出这样的一个呃警告呢?其实这个警告对于你的程序啊没有任何影响,就是你该怎么写还是可以怎么写的,但是程序员一看见红色就比较眼红,对吧?哎,那这是为什么呢?因为咱们需要给这个promise传入相应的成功与失败的回调,那这样就可以捕获到这次promise的异常。那所以说啊,其实解决它的比较好处理。怎么处理呢?就是在调用push的时候,咱们已经传递了一个参数,往哪跳,哎,你在给他咋的呢?再传两个参数,比如说成功的回调给push传过去对吧,以及失败的回调,那这样就可以解决这个问题。对吧,你看咱们可以试一下的,比如说123,你看老师点击多次他也没问题啊,当然现在它返回的是按底发。
06:00
对不,所以说这样的它呢是可以解决这个问题的,而且可以在失败的这个函数当中啊,捕获到这个错误,咱们可以打印一下你看。Log error对吧,你看咱们呢,可以打印一下老师刷新还是来个123,你看它是可以捕获到这样的一个错误的啊,当然咱的造的是不是已经删了。对不,那所以说咱们可以看一下,你看老师点击多次对吧,我来个123,它是可以咋的,是捕获到这次异常的,那如果你不在这打印,OK,那控制台当中他就打了,是不是就不显示了。对吧,所以说可以通过传入相应的成功与失败的回调去解决这样的一个问题。那所以说啊,咱们也去做一下笔记,哎1.2怎么解决,比如说啊通过给给谁呢?给push方法。
07:01
哎,传递相应的相应的成功,还有是失败的啊回调函数。那么可以捕获到,哎就说捕获到哎当前的啥呀,错误对吧,可以解决,哎可以解决,哎解决。对,不但是吧,你得琢磨琢磨,如果是这种写法吧,它只治标不治本。什么意思呢?也就是说这种写法你确实能解决这样的一个警告的一个错误,但是他治标不治本嘛。你看老师写下一点几,1.3,也就是说通过底下的代码写一下,就是通过底部的代码。哎,代码对吧,那么可以实现解决这个错误。但是你要注意一件事儿,这玩意儿它治标不治本。什么叫治标不治本呢?
08:00
对吧,比如说写一下这种写法。他也就是治标不治本,什么叫治标不治本,那举个例子,那我将来在别的组件当中。对吧,哎,当中我不管是push或者是re replace Rep replace,那么编程式导航啊,编程式导航,哎,导航还是有类似的错误。是什么意思呢?比如说咱们将来的组件有100个,这100个组件呢,还有push或replace方法,那你点击多次,它还是会报这样的错误,那你还是得在这里传成功与回调。对吧,而且还麻烦,一传要传100次。那所以说啊,咱们呢,想给他治。本。对不什么意思呢,就是咱们给的这个问题彻底解决了以后,再调push和replace的时候,就没有这样的一个方,这样的一个错误,那咱们要解决这个问题,那你还真得看看这块的代码,咱们得研究研究。
09:10
对不?所以说你看咱们去研究一下,得研究啥,得研究这个push是谁的。对不?哎,咱们先琢磨琢磨,那首先说这次是谁,你看啊。This。This是当前的组件实力,这是毋庸置疑的,咱们可以看一下打印给123对吧,随便来一个打印this,你看this是view complement类的一个实例,那当然就是一个组件实例。那么在他的身上啊,有一个这样的一个属性叫做Dollar router。对不对,那咱们呢,可以点一下哎,点Dollar router,那么组件实例的这个这点Dollar router是从何而来呢。
10:00
是当年咱们注册路由的时候。是不是给组建实力身上添加什么?所以说啊这块呢,要注意一件事儿,咱们就研究研究这几行代码,谁呢,虽然说这是谁face呢,是当前。写一下当前组建实力是谁的实力呢?就是。对吧,而你的这点Dollar router属性。啊,比如组建实力的这个属性,你要注意它是一个对象。你看咱可以再看一下,它是一个对象。对不对,而且是view root类的一个实例,也就说写一下,也就说当前的这个属性。当前的这个属性,它的属性值啊是VE,哎,V UE router。类的一个实力,哎,类的一个实力。
11:03
对不,那以及他从何而来呢?对吧,就是当注册路由的时候说的更准确一些,就是当。在入口文件注册路由的时候,那给组建实例添加的啊实例哎,添加的这个Dollar router。还有这个谁呀,Dollar root这样的一个属性。对吧,那以及咱们再看一下的他呢,在打点push的时候,那咱们得研究研究push是谁的方法。对不,那咱们可以看一下,你看这老师打印一下。你看现在打印的这个是什么呢?就是root类的一个实例,就是咱们当前组建实例的一个属性,叫做Dollar routeer是e rooter类的一个实例,你看实力的身上有这个push方法吗?
12:00
有吗?没有对吧?它是谁呢?它是will router这个类的原型对象上的方法叫做push。对不对,所以这块要注意一件事,什么事呢?就是咱们的这个,呃,这个这个push方法,他是谁,他呢是VE。Router类的一个实例。对吧,那所以说啊,老师呢,大概的给你们说一下,你看啊,就举个例子,这是组件实例。对吧,它的Dollar rooter属性是什么呢?是VE多会VT呀,Router类的一个实例。而且viewor呢V,它的原型上pro有一个push方法。对不,咱们写一个伪代码,那也就是说你组建实例。
13:03
对不,组件实力身上的这个属性Dollar router,其实上它就是UE router类的一个实例,你看比如咱模拟一下叫做Dollar router等于什么?等于new一个V,哎,V u t router。其实咱们的这个组件实力身上,这个到了rootor属性啊,就是v UE routeor类的一个实例,咱们刚刚也看见。而view router类的这个实例啊,可以借用原形对象上方法对不?你看比如说导route点这个push往哪push叉叉叉。对不,所以说这个呢,是它原型对象的方法,哎,原型对象的方法。那所以说这块要注意一件事,那么当这点这点到route,也就是这个view root类的这个实例,打点push这个方法的时候要注意。
14:02
要注意这个函数的上下文是谁呀?那这个函数的上下文为谁呢?为VE。I router。类的一个实例,你琢磨琢磨,是不是这个道理?你自己琢磨琢磨,这块一定要耐住性的去琢磨,因为这块涉及到了类和啥呀,原型,也就是说你这行代码,你要注意这是组件实例。他的身上呢,有一个Dollar router的一个属性,它是will route类的一个实例。那view以router类的实例可以借用原型对象的方法,而这个原型对象的方法的上下文是谁?那不就是route特类的一个实例吗?对不,那所以说如果咱们想治本,那你得重写will router这个原型对象身上的这个push方法。对不?而且还要注意,咱们利用的是人家标route本来就提供的这个push方法,给他重写一下。
15:07
对吧,那所以说那怎么去重写,那你得找到带有will router的地方,那一定是哪一定是路由,这里咱们可以看一下。你看吧,在路由这里啊,咱们呢,是能获取到view router这个类。对不,那咱们呢,可以打印一下,你看老师给你打印一下子就是voe router。咱们呢,瞄一眼你看啊,走,它是不是就是will router?它是一个类,是一个构造函数,而它的原型对象上pro type是有这样的一个方法的,叫做push。对不对,咱们找一下是不是有这个push方法。所以说咱们要重写这个push方法。对不,那所以说咱们在这儿得搞搞对吧,那第一件事儿干什么呢?对吧,你就先把。
16:05
VI router。圆形。对象的push方法你先咋呢?先保存一份,哎,先保存,诶保存一份,那为什么要保存呢?因为说白了你进行路由跳转,你还是得用view root.pro用这个push方法。说白了,咱们呢,还是用人家已有的破世方法,只不过稍微封装一下,进二次封装。对不,那所以说咱们可以来一个呗,那你就light一个,比如说叫起源,叫做or push。对,不,那等于什么?等于view router.type.push方法。那这行代码老师做了一件事,什么事,就是把人家will rootor原型对象这个push方法我备份了一下。
17:01
那也就是说,将来咱们实现路由跳转,解决这个问题,还用的还是人家的这个push方法。对不对,那所以说来看这,所以说咱们要备份一下,那接下来咱们呢,就重写什么,重写vuee啊,就是重写这个push与这个replace方法。对不,那所以说咱们搞一下呗,就是VE。ro.pro type.push那等于什么呢?等于function。那咱们呢,先alert一下,那也就是说VE pro.push原来人家已有的方法就已经失效了。你现在点击他白扯了,他只能谈123了。对吧,当然你这块的你部署也123它也一样,就你点哪都一样,它push方法已经重写了,变成了这个方法。对不?那你得琢磨了,将来咱们路由跳转还是得用人家已有的这个铺设方法,只不过咱重新给他重写一下。
18:10
那你得琢磨琢磨了。当路由组件调用push方法的时候,你要路由组件的这个这点root.push方法,那现在调用的不就是这个方法,你点击弹出123。那你得琢磨琢磨,这块需不需要传参了,需不需要,那一定是需要的,你push的时候,你将来往哪push?那你这块的参数是不是该传的,你还是得传。你琢磨琢磨,是不是这个道理,你得告诉人家,将来人家用原来的这个push方法,你得告诉人家往哪儿跳啊,所以这块你得传一个叫啥叫location往哪跳。那第一个参数,第一个参数是什么,就是告诉啊人家原来的复试方法。对吧,你往哪里啊,就是网应该是哪个网,是这个网往哪里跳。
19:05
对吧,哎,跳转以及传递哪些参数。对吧,哪些参数,所以location你得传的,那以及你要琢磨琢磨,那用户将来这里呢,他可能传成功,失败的回调也有可能不传。但是我不管你传不传,我这块我都接受一下子叫做。还有谁呢?Reject,成功与失败?那接下来有的同学可能会想到那老师,我知道了。那无非调用push方法,往哪push不就行了吗?那如果你传回调往这个函数里面一扔扔沙餐,那不就完事了,但是你这里要注意一件事啊,就是上下文的问题。最开始老师也说了。也就是说你调用人家原来的这个push方法,它的上下文,你务必要保证什么,保证调用的是vur类的一个实例。
20:01
而咱们现在调用这个push方法,OK,它的上下文是谁呢?其实那不就是用rootor类的一个实例。咱们可以打印一下,你看嘛,Cons第2LOG this。对不?咱们打印一下,你看现在咱不谈123了,只要我一点击走,你看它是不是voe router类的一个实例。那所以说这里面咱们得咋的了。得判断分两种情况,第一种你看啊,如果你的resolve你传了,且你的reject也传了,就是成功与失败的回调,你传了OK,那你就调用原来的这个push方法,但是你要注意,你不能这么调。你要这么调,你导致的,人家原来这个push方法的上下文是谁的,是window了,是函数音加小框调用是window了,所以说你这么调它不行,你得怎么调,你得这么调用扣。
21:01
对不,那也就是说我调用了原来人家的这个push方法。我调一次,而且我还要给他篡改一下上下文,为什么呢?为will router类的一个实例。那咱们刚刚也看了,你现在调用的这个方法,那不就是类的一个实例吗。对不?对不对,对吧,那也用的是人家原来已有的普世方法。那以及你要告诉人家你往哪跳啊?所以得传参。而扣和a play,咱当年说过,就说扣与a apl ly play的区别。虽然说相同点,相同点是什么都可以,哎,调用函数一次,而且都可以篡改函数的什么呀?哎,就是篡改函数的上下文一次。对,不但是要注意区别是啥。
22:02
之相同点,那不同点是什么?不同点写下不同点。那不同点呢,就是扣与。传递参数的区别。扣传递参数,用多个参数用逗号隔开。哎,逗号隔开。对吧,而你的a play方法。哎,执行你要干什么,传递数组,那所以说这行代码怎么保证了人家原来已有的push的方法,上下文它还是谁,还是u uor类的一个实例。但是你接下来你要告诉人家,你往哪儿跳?对不,那就是谁location。那以及如果走了这个分支,那你一定是传了成功与失败的毁掉,那就是谁。以及谁呢?那当然else代表啥?那else代表的有可能是resolve有或者reject没有,或者是reject或者resolve没有,那所以说咱们就可以怎么办,Push点扣。
23:08
还是this?对吧,以及往哪调location,那当然咱这块就自己手动的传入两个回调不就完事了。对不,那所以说那这样不就治本了吗。所以说我不管你在调用这个构,重构的这个push方法,是传了这个回调还是没传,OK,我都可以解决这个问题。其实你回首再看一下这里,其实这块一点难度都没有,其实无非就是对于原型类的理解,那你看最开始咱们没重写之前,你调用push置方法,你是不是要保证它是voer类的一个实例,因为它的上下文是voe rootr类的实例。对不?那所以说咱们重写之后,你自己要看看,那我要保证上下文为为什么为没有rootr类的一个实例,而且我调用的还是用人家原来已有的这个铺食方法,以及该传参传参,对不?那所以说咱们回首再看一下子,那这个问题不就解决了吗?比如咱来个123,你看你怎么点它都没问题。
24:16
对不?你狂点他也没问题。所以说咱们重写了一下子人家原来的push方法。当然老师呢,把这块呢也给你扔到顶上,因为有的时候面试的时候啊,他有的时候会问你对吧,这种初级的会问你,哎,这个push啊与a play有什么区别啊,那所以说这里你得知道。对吧,以及还有一个东西叫做B,那如果说你玩react应该用过对吧。那当然,咱们目前而言只重写了谁啊?重了这个push方法,当然还有谁replace,那就like一个叫做or replace方法。对吧,那还是把人家原有的replace方法你进行备份。
25:00
对不,那当然底下这儿还是要得重写。对吧,重写replace方法那也是一样,Will route第2type.replace。那也是一样,也需要传,告诉人家将来调人家原来这个replace方法,告诉人家往哪跳对不?哎,往哪跳low,但是你叫别的也行,成功的回调。Resolve。对吧,以及失败的回调。对吧,那这块老师写什么,第一个参数,第二个参数是啥,是成功的回调对吧,那第三个参数呢?第三个参数是失败的回调,当然你的行参叫什么名字都可以,你叫ABC它也行。对吧,那这里也是一样,你也要判断,就是如果你传了成功或者是失败的回调,那你就可以写了,叫做啊replace打点谁啊打点这个空。
26:01
对不,当然this,以及往哪跳,Location,以及成功以及失败,对吧?成功是失败的是reject。对吧?那当然有一个没传,那你就自己手写一个吗?Replace,点空还是谁呢?This,以及location,以及成功的毁掉,以及失败的毁掉。虽然这样的一劳永逸,以后再调用push和replace的方法呢,食指就是调重写的,但其实你再想想,其实食指呢,还是用人家原来的这个push方法和replace方法,你只不过稍微加工一下。对吧,就是看后面有没有这两个成功与失败的回调,有我就写上,没有那没给我传,我自己手写。对吧,那所以说那这样咱们就不完成了这个呃,问题的解决了嘛,对吧,所以说这个问题呢,还老师还是那句话,你可以重写也可以不重写,对于你的程序呢,没有太大的影响,以及声明式导航是没有这样的一个问题的。
27:09
所以说这个问题需要注意一下。
我来说两句