正常的思维
做多vue页面应用,我们的第一反应是配置多个入口点,多个vue应用,编译成多个HTML文件,由服务器来决定路由。这是正常的思维。
但谁知道单页面应用也能做到类似的效果呢。单页面不过是服务器路由变成了客户端路由,但通过一些技巧,也能实现类似服务器多页面路由的效果。
客户端路由多页面的实现方式
我以vue-router
举例
多个根路由
最简单的多页面应用,是设置多个根路由。这样在新标签页打开不同的根路由,就相当于多页面应用。
只是实际上,这些不同的标签页还是同一个vue应用。不过是呈现了不同的组件罢了,网络请求的js资源还是一样。
比如这种
const router = new VueRouter({
routes: [
{
path: '/parent',
component: ParentComponent,
},
{
path: 'standalone-child',
component: ChildComponent
}
]
})
可以在两个标签页打开,http://5234/#/parent
和http://5234/#/standalone-child
。两个组件的内容互不干扰。
看起来客户端路由是利用锚点实现的。
但这无法解决嵌套路由的问题,
比如
const router = new VueRouter({
routes: [
{
path: '/parent',
component: ParentComponent,
children: [
{
path: 'child',
component: ChildComponent
}
]
},
{
path: '/standalone-child',
component: ChildComponent
}
]
});
我们访问http://5234/#/parent/child
居然会把http://5234/#/parent
路由的ParentComponent
组件的内容显示出来。
ChildComponent
看起来似乎就像一个iframe
一样呢。
虽然有时也需要这种效果,但有时也需要这个“iframe”独立显示。我们需要这种控制权。
条件渲染与查询参数
实现的方式是在router配置中使用路由参数
+ParentComponent组件中使用条件渲染
- 首先在路由配置中增加路由参数:standalone
const routes = [
{
path: '/',
component: App,
},
{
path: '/parent',
component: ParentComponent,
children: [
{
path: 'child/:standalone',
component: ChildComponent
}
]
},
{
path: '/standalone-child',
component: ChildComponent
}
]
- 修改父组件
我们在父组件中根据standalone
取条件渲染。当standalone='standalone'
时,就只渲染router-view
,否则就使用“iframe”的方式。
<template v-if="$route.params.standalone!='standalone'">
<h1>parent</h1>
<router-view></router-view>
</template>
<template v-else>
<router-view></router-view>
</template>
其效果如下
好处是实现了“iframe”和独立标签页两种形态,缺点是路径变长了