umijs 踩坑记录

再次使用 umijs,然后踩了一些坑。之前之所以没发现,是因为没有触发。

路由拦截拦不住 model 层

umjs 可以在两个地方进行路由拦截,一个是 app.ts 里配置 onRender 函数。还有一个是在 src/layouts/index.ts 里拦截。相对来说,在 layouts 里更自由一些。但不管是哪个,都没能拦住 model 层。这与我们之前的 dva 项目不同。之前的 dva 项目不管视图层还是 model 层,都是按需加载的。所以可以成功拦截。

// 之前不使用 umijs 的项目
// 回款情况
{
  path: '/repaymentSituation',
  models: () => [import('./models/repaymentSituationM')],
  component: () => import('./routes/repaymentSituation'),
},

因为 umijs 的 model 层是一次性加载的,在拦截器拿到用户数据之前就会进行路径判断、数据初始化、发请求等操作。很显然这不符合需求。

为了解决无法拦截 model 层的问题。我只能把 model 层引用到的文件里需要根据用户信息等初始化的数据的初始化操作延后。model 层 setup 部分判断路径发请求的代码删掉,在组件的 componentDidMount 里触发请求数据操作。

另外,在 layout 里拦截的时候,我还添加了跳转 redirect 页面的操作。没有获取用户信息就发请求,同时跳转 redirect,拿到信息之后再回到原来的页面。这个是为了二次触发 setup 阶段的路径判断。这样可以把部分初始化数据的操作放到 setup 阶段。

新建页面不显示

这一点文档里提到,新建的页面需要返回 jsx 才会自动创建路由。也就是说,返回字符串是无效的。

// 这是无效的
export default function page() {
  return '新页面'
}

model 层无法存储函数

也许 sage 的文档里有提及 store 里可以存储的数据类型,但我没找到。在写之前有意识到可能不能存储函数,但还是尝试了一下。这让我不得不把看板的配置数据(包括自定义函数)和请求获取的数据分开。

postcss-px-to-viewport 配置

因为需要把看板的 px 单位转为 vw,所以需要用到 postcss-px-to-viewport 插件。但是,这个插件不支持 include 选项。github 里版本倒是支持,但 npm 上的不支持。后来找到了 postcss-px-to-viewport-with-include 这个插件。两个都安装,然后在 umirc.ts 里配置。

extraPostCSSPlugins: [
  require('postcss-px-to-viewport-with-include')({
    viewportWidth: 1920, // 视窗的宽度
    unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
    viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw
    selectorBlackList: [], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
    include: [/\/src\/pages\/board/, /\\src\\pages\\board/], // unix 路径和 windows 路径
    minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
    mediaQuery: false, // 允许在媒体查询中转换`px`
  }),
],

其中,include 配置了两种路径,因为插件不能自动转换。

其实对于 px 转 vw 我还是有点不满足。因为看板需要宽高都适配,如果只能转换一个单位,就意味着大部分情况下还是需要用百分比。如果不用这个插件,倒是可以 vw 和 vh 都使用,但手动计算太累。