项目场景:
点击侧边菜单栏切换页面
问题描述
页面无法跳转,一直报如下错误:
TypeError: Cannot convert undefined or null to object vue.runtime.esm.js?2b0e:1888
at Function.keys (<anonymous>)
at eval (vue-router.esm.js?8c4f:1817:1)
at Array.map (<anonymous>)
at flatMapComponents (vue-router.esm.js?8c4f:1816:1)
at extractGuards (vue-router.esm.js?8c4f:2063:1)
at extractLeaveGuards (vue-router.esm.js?8c4f:2086:1)
at HashHistory.confirmTransition (vue-router.esm.js?8c4f:1942:1)
at HashHistory.transitionTo (vue-router.esm.js?8c4f:1890:1)
at HashHistory.push (vue-router.esm.js?8c4f:2291:1)
at VueRouter.push (vue-router.esm.js?8c4f:2581:1)
如下图点击账务库存查询一直无法切换到对应页面,路由地址也没改变,点击库存查询一直报上面错误:错误内容是不能将非对象类型数据转为对象。
原因分析:
按照错误提示是数据处理的问题,可是按照报错位置排查发现代码中没有任何关于将非对象数据转为对象的处理。
于是我就点击控制台下图所示报错具体位置去查看路由源码
发现是路由底层代码实现报错,并不是个人写的代码中报错,在下图路由源码中发现是 m.components 值为未定义,而路由matched参数是匹配到的当前页面的每一级路由对象数组,里面components是当前路由注册时设置的组件component,但现在是空的,然后我就在控制台打印了 当前页面 $route.matched,发现该参数只有前三级路由数据正常,后面多出来一些自定义数据,于是就明白了应该是代码里有对 route.matched做修改,最后查找代码发现没有直接做修改,而是在读取 route.matched 数据时,没有考虑到是浅拷贝,后续其他地方对读取到的数据做处理时,都会影响到 route.matched。
可以看到报错时控制台打印的 $route.matched 中第四个元素是自定义添加的数据,和 route 源码中处理的数据不一样,而 route.matched 路由底层处理的数据,我们是不能去改动它的
读取数据时,在处理时忘了深拷贝,下面是处理好的代码
解决方案:
在需要用到 route.matched 数据时使用深拷贝,这样后续对数据的修改就不会影响到路由的参数啦。因为我这里只用到title,path属性值做面包屑处理,所以直接用下面方法就可以,了解深拷贝方法可以看这里手写深拷贝: