首先附上[代码链接](https://github.com/JqhSdtz/laputa_sns/blob/master/vue-lpt/src/modules/blog/router/index.js ),所使用的Vue Router版本为4.0.5,[4.x中文文档](https://next.router.vuejs.org/zh/introduction.html )。 首先解释一下标题。两个视图是指页面中的两个部分,即两个router-view,分别独立路由是指两个视图中的内容互不干扰,一个视图中的内容改变,另一个视图保持原样。具体例子就是本网站左侧抽屉弹窗和主页面。通过这种方式,页面内容可以非常灵活的变化。 在很早以前各种前端框架还没兴起的时候,可以使用iframe来实现这种效果,这也是当时的大多数以及现在的一部分复杂页面的构成方式。但iframe有一个缺点,内部iframe变化不会体现在url中。这样用户在iframe中不管跳转到哪,刷新一下都会回到初始页面。现在如果使用Vue框架的话,基本可以通过组件化和路由革了iframe的命。 对于管理系统那种左侧菜单树右侧内容区的页面,其变化的区域只有一个,Vue Router可以很轻松地实现。但如果需要页面内两个区域都要变化,且相互独立,Vue Router就不能直接实现了。但Vue Router有一个强大的功能,导航守卫。通过导航守卫可以做的事情非常非常多,当然也可以实现这种需求。 [众所周知](https://next.router.vuejs.org/zh/guide/essentials/named-views.html ),Vue Router可以在一个页面创建多个视图,一个路由记录(RouteRecord)可以匹配多个路由视图。例如: ```javascript const record = [ { path: '/part1/part2', name: 'index', components: { part1: Part1, part2: Part2 } } ] ``` 如果两个视图分别要展示的内容为组件Part1和Part2,那么上述路由记录就可将url路径“/part1/part2”指向这两个组件,即页面两个区域分别展示这两个组件。这就是实现两个视图分别独立路由的关键。看起来非常简单,实际上也就是这么简单。。。 但是问题来了,既然两个视图是独立无关联的,那么代码中的url必然是'/part1','/part2',路由记录也必然是只有part1和只有part2。 解决路由记录的独立很简单,把两个视图需要用的路由记录分别列出来,两重循环把每一种可能的组合都创建出来,然后再执行`createRouter`即可。 解决url的独立就比较麻烦了。基本思路是在`router.beforeEach`,即路由前置守卫中判断原始的路由记录是对应的哪个视图。判断方法可以使用路由元信息(meta),路径的规则或者请求参数。如果一个路由记录对应的视图是唯一的,直接在路由记录中添加meta即可,每次路由解析时判断是哪一个视图,记录下每个视图当前的url,并且将另一个视图当前的url和本次路由的url拼接起来,形成完整的url,然后Vue Router根据这个完整的url找到对应的组合而成的路由记录,即可实现在不影响另一个视图的情况下对某个视图进行路由。 组合url的回退是一个问题。如果要实现独立路由的话,在一个视图内点击浏览器的回退按钮,应该针对这个视图做回退,另一个视图不能受到影响。其实现的基本思路是手动记录每个视图的路由历史,回退时取对应视图的历史url,和当前另一个视图的url拼起来,再做一次路由。 这里有一个问题是如何在前置守卫中判断是回退操作。首先回退操作也是会经过前置守卫的,但是不会经过`route.push`。可以覆盖`route.push`,实现对每次push操作的捕捉,然后将不经过push直接到前置守卫的路由操作认定为回退。 判断当前是哪个视图根据具体页面具体实现。