离谱架构系列——我在PC管理平台项目中写移动端页面

292 阅读4分钟

项目背景

一个多角色的PC端项目,使用的技术栈是Vben-Admin,一个做了高度封装的管理平台系统。管理员角色几乎都是表格查询,用户角色需要做申请操作,而移动端的适配仅仅是使用了CSS修改了页面样式,导致用户体验非常差。本来想针对移动端专门建一个项目,但项目周期紧迫,没有时间把登录、授权等模块重写一遍。针对时间紧任务重的现状,我们不得不写一些“笨代码,在这个项目的基础上再度引用Vant组件库,额外针对用户角色开发一些移动端页面。

探索了以下几个问题后,我终于完成了一个初步的版本:

icon不展示

怀疑是内网开发环境下加载不了iconfont文件,但最新的vant已经解决了这个问题:

源码里已经转成base64了,不存在引用第三方文件的问题。

发现是原来的项目已经全局使用了字体,

.iconfont,[class*="icon-"] {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

修改方式:

.van-icon {
  font-family: 'vant-icon' !important;
}

如何跳转到移动端的页面

// 登录页、找回密码页使用原来的页面
if (['Login', 'InitPassWord'].includes(to.name)) {
	next();
	return;
}
// 当前环境是移动端并且路由上面没有mobile标识,就跳转到移动端的首页
if (isMobile() && to.path.indexOf('mobile') < 0) {
	next('/mobile/home')
	return
}
// 当前环境是PC端并且路由上携带了mobile标识,就跳转到PC端的首页
if (!isMobile() && to.path.indexOf('mobile') >= 0) {
	next('/home')
	return
}

然后所有移动端特有的页面,我们在路由定义的时候都加了一个mobile

公共的错误提示处理

在PC端,我们使用了ant-design-vue的错误提示,这里需要判断设备

if(isMobile()) {
	showToast(alertMsg)
} else {
	createMessage.error(alertMsg);
}

移动端适配

使用postcss-pxtorem插件对业务代码里文件路径包含mobile的,和vant组件库进行处理:

// postcss.config.js
module.exports = {
  plugins: {
    'postcss-pxtorem': {
      rootValue: 37.5,
      propList: ['*'],
	  include: [/mobile/, /node_modules\/vant/]
    },
  },
};

vant分包

我们从PC端进入页面,事实上是不希望加载移动端的代码的,我们在这里把vant组件单独抽离出来,只有进入移动端页面,才会去加载资源。

rollupOptions: {
  output: {
    manualChunks: {
      vant: ['vant']
    },
  }
}

想法是好的,但实际上没有作用,如下图,是在PC端登录页渲染的时候就已经加载了vant,原因在于上面对公共的错误提示处理引用了vant组件,因此就随着公共模块加载了vant。

image.png

unplugin-vue-components 带来的问题

vant官网上有一个unplugin-vue-components插件,可以自动引用vant组件,尝试之后发现了诸多问题:

import vue from '@vitejs/plugin-vue';
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';

export default {
  plugins: [
    vue(),
    Components({
      resolvers: [VantResolver()],
    }),
  ],
};
  1. PC端组件也被实时设置成了公共组件,原因是该插件会去遍历src/components的vue文件,而我们的Vben-Admin项目正好有这个目录,并且存放了很多组件

image.png

这样导致我们本来不用处理的组件都被处理了。

  1. 每次项目启动,都会处理两遍,原因是该插件会去实时生成components.d.ts。如下图所示,组件引用会在编译的过程中发生变化,因此每次运行项目都会重启一次,如果某个页面又引用了之前没用过的vant组件,又会触发两次编译。

image.png

综上,使用这个插件只是在引用vant组件的时候少写一行代码,但时间代价是巨大的。

处理了上面的问题之后,我们成功在PC端项目里造了一部分移动端页面,结构调用、权限等功能都可复用。虽说项目架构比较离谱,但在短期内交付这个项目,已经是比较合适的方案了。

优化空间

  1. 移动端和PC端一般是两个不同的项目,合二为一会在运行时产生造成大量的冗余逻辑判断,造成性能问题;

  2. 我们把两个项目合二为一的重要原因之一,就是希望可以复用一些通用的逻辑,例如权限控制、接口调用等等。如果我们把这些模块拿出来放到组件库中,那么另起一个项目做移动端的成本就会大大降低;

  3. 由前端控制路由跳转,不够灵活,一般是通过Nginx配置跳转。