Vue多页面应用配置

JavaScript015

Vue多页面应用配置,第1张

最近由于工作驱动,项目包含pc端及mobile端,pc端和mobile端核心功能一致,最大的不同是UI,为了减少维护的成本,决定使用Vue的多页面开发。

项目线上部署在一个子目录下,为了解决在本地和线上路径保持一致,需要修改一些配置。所以以此篇文章来记录一下配置过程中的问题。

这里是我放在github上的项目,里面有整个配置文件。感兴趣的朋友可以参考一下: vue-multiple-page

此篇文章记录了先在根路径下的多页面配置,再从根路径修改成子路径的配置

vue脚手架vue-cli3及以上;

在本地用vue-cli新建一个项目;

vue3.js :路由配置修改的是 history: createWebHistory('/mobile/')

vue3.js :路由配置修改的是 history: createWebHistory('/e/')

mobile端mobile.js的base修改成 base: '/e/mobile'

vue3.js :路由配置修改的是 history: createWebHistory('/e/mobile')

特别注意的地方

应用系统中需要运用到多标签页,跟浏览器一样的效果,在新打开页面后,动态追加一个页签,点击页签可以切换系统主页面区域的内容,且保持内容不刷新,如果关闭页签再通过菜单打开,重新加载。jQuery年代的解决方案就是ifream,但是在Vue.js的单页面应用中,都是组件化开发了,实现多标签页解决的问题就聚焦在关于组件实例的缓存和销毁,下边讲述两种实现多标签页系统的技术实现方案。

Vue Router是官方的路由管理器,跟Vue.js深度集成,确实很强,更多的功能不意义阐述,详情请参考 Vue Router 官方文档

当我们跳转一个新的路由时,可能是点击菜单,也可能是点击发生跳转,这时候路由会发生切换,我们都希望打开一个新的页签,并且这个页签并处于激活状态,当打开多个时,可以切换页签的激活状态,同时路由组件区域(页面内容)发生变化,始终展示激活页签对应的内容。

一个组件展示所有的标签页,并标识出来哪个是激活状态,标签页数据需要在菜单等地方实现追加,我们优先选择数据存在Vuex中,由标签页组件实现切换激活标签和删除标签,添加标签页也可以在该组件内实现,需要对路由进行监听,路由发生调用Vuex中的增加函数,函数对路由数据进行过滤,这样就可以实现路由变化时,标签页数据的变化。

在<router-view/>外层包裹 <keep-alive>具体原理参考 在动态组件上使用 keep-alive

这个时候,在你切换渲染不同路由的时候,确实好使,组件的状态数据、表单填写的内容等也会被缓存,好像这么简单都直接解决了,当然不可能,这么简单就没必要写这篇文章。

当你更改路由参数的时候,你会发现参数变化的时候,不太好使了,会把之前缓存的这个组件销毁重新加载, 一个组件只能被缓存一个 ,我们希望的肯定是参数不一样时,应该分开都缓存,比如一些明细页面,我们需要看多个客户、多个工单,不应该每次切换都是在重新加载。

关闭页签时,我们更换路由,实现跳转,当再次访问这个路由时,组件未重新加载,这个就不符合正常的使用习惯,关闭页签就应该啥都没了,所以缓存啥的应该都没了。

组件有没有缓存可以通过DevTools调试查看

这样看起来,好像才是真的解决了所有的问题,但是还是有bug,有瑕疵, 解决方案2 中提到的一大堆过程的前提是 destroy ,只有组件进入 destroy 才满足 解决方案2 的方法,但是如果页签没有激活,keep-alive中就已经是停用了这个组件,关闭页签时,路由是没有变化的,keep-alive对各个组件也并没有发生启用和停用,只是改变了Vuex中 visitedViews 的数据,所以关键问题是只要 visitedViews 发生变化,需要把减少的那个组件给卸载掉。

至此,卸载这个活儿终于完成了,无论是怎么关闭页签,都可以完成组件的卸载,切换页签不卸载。感觉完美无瑕,可现实总是那么残酷,关闭页签后,再打开,切换页签时,这个组件 居然刷新了 ,明明关闭前,切换是不刷新的,关闭再打开后,就会刷新了,难道不会缓存了?看一下DevTools调试,懵了。。。

<keep-alive> 添加 include ,Vuex获取当前打开页签的组件名(如:visitedName),include=visitedName;针对传参数的页面,添加 watch ,监听Vuex中标签页的变化,当有变化时判断是否包含当前组件,没有时卸载当前组件,当组件不需要传参时可以不添加watch,include不缓存时组件将会被卸载。

注意: 页面组件必须写name,声明组件名称

npm run build 之后将 dist 放到Nginx目录就行?

再多几个需求就不简单了:

一步一步来

假如 我们项目有两个入口: pc 与 mobile, 我们需要修改 这几个地方:

按照vue-cli的 官方文档 配置多入口并不难:

页面入口名字 即 mobile 只会影响在开发环境的入口: 现在需要使用 'localhost:3000/index' 和或者 'localhost:3000' 来进入 index 页面, 使用 'localhost:3000/mobile' 来进入 mobile 页面.

filename 会影响在生产环境中打包出来的入口文件(.html文件)路径. 值得注意的是 mobile . filename 字段: 我设置的是 mobile/index.html , 而不是 mobile.html , 这是有原因的, 在下面配置nginx时会说到.

配置好vue.config.js之后打开 'localhost:3000/mobile' 却发现空白, 进入不了mobile的路由.

查文档 VueRouterApi-base , 发现需要配置 base.

官方文档只是举了一个例子说部署在/app/下可以设置base, 但多页面也需要如此配置.

如下:

mobile.router.js

现在访问 localhost:3000/mobile 就能正常进入.

至此, 开发环境没问题了. 接下来是部署.

我使用nginx作为web容器部署前端项目, 其他服务器大同小异.

我们需要将 npm run build 打包出来的 dist 文件夹下的所有文件放置到nginx所在服务器的 /usr/share/nginx/html 目录下. (目录可以自定义)

nginx.conf

其中为了支持VueRouter的History模式, 我们需要按照官方文档配置: HTML5 History 模式 .

又得益于我们将 mobile 入口的输出文件地址修改为了 mobile/index.html , 正好访问 /mobile/ 时让Nginx打开 mobile/index.html 文件, 所以它足够简单.

如果你只有需求将项目部署在根目录, 那么现在便完成了.

假如需要将项目放入 www.example.com/app/ 下, 访问 www.example.com/app/ 进入index入口, 访问 www.example.com/app/mobile 进入mobile入口. 则在上述 ‘部署到根目录’ 基础之上还需要修改以下几项文件:

pages 中需要修改的是 两个入口名字, 修改为: app/index 与 app/mobile .

在上面说了, 页面入口名字 即 app/mobile 只会影响到开发环境访问入口: 现在在开发环境访问 localhost/app/mobile 才能进入 mobile 页面.

如果我们需要在生产模式也使用 domain/app/mobile 路径访问项目, 还需要修改: publicPath 和 outputDir

修改base, 如下:

mobile.router.js

A: 修改outputDir是为了不修改nginx配置. 不修改outputDir也是可行的, 那么需要修改nginx配置如下:

少改一个文件是一个, 所以我推荐修改 outputDir .