Taro 多端统一开发解决方案上手

dev 2023-02-08 18:39:27 #前端开发 #大前端 316

最近又遇到了微信小程序开发的需求,但实在是不想再用微信那套自己的开发框架,于是转头开始尝试小程序方面多端统一开发的解决方案。

在这方面比较成熟的有 uni-appAPICloudkbone 和 Taro,抛去商业化严重的 APICloud 和生态欠缺的 kbone,便留下 uni-app 和 Taro 两个解决方案。虽然没接触过后者,但由于我一直莫名不太喜欢前者,故还是选择了 Taro 进行开发。

简介

Taro 是一个开放式跨端跨框架解决方案,支持使用 React / Vue / Nerv 等框架来开发 微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ / 飞书 小程序 / H5 / RN 等应用。

现如今市面上端的形态多种多样,Web、React Native、微信小程序等各种端大行其道。当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。

官方文档的简介浅显易懂,便直接引用了。在 UI 方面,使用的则是京东自家的 NutUI,因为其完整度、生态丰富度、迭代频率都比 Taro-UI 更高。并且 NutUI 直接支持 React 和 Vue 这两大技术栈,而 Taro-UI 对 Vue 的支持需要自行调教。

至此,我的使用技术栈是 Taro 3 + Vue 3 + NutUI 4 + Tailwind 3,以及 Webpack 5 和 Typescript。不得不说 Vue 3 的组合式 API 让我有了一点写 Svelte 时候的顺畅感,顺带一提状态管理用的 Pinia

开发配置

实际上手后我主要依靠 H5 端进行开发调试,一开始便遇到了字体大小的问题:在 H5 移动端字体被自动转换得过大。查看文档后发现是其默认配置导致的,也就是 pxtransform 对象。

const config = {
  h5: {
    postcss: {
      pxtransform: {
        enable: true,
        config: {
          onePxTransform: true,
          unitPrecision: 5,
          propList: ['*'],
          selectorBlackList: [],
          replace: true,
          mediaQuery: false,
          minPixelValue: 0,
          baseFontSize: 20,
          maxRootSize: 40,
          minRootSize: 20
        }
      }
    }
  }
};

按照 Chrome 默认参数,将 baseFontSize 和 minRootSize 分别调整为 16 和 12 即可。

至于其他便捷开发配置,Taro 官方文档中有大量说明,例如目录别名和编译优化等。同时,你也可以通过其提供的教程进行系统性的快速了解。

需要注意的是,Taro 转小程序似乎并不支持直接解析类似于 /pages/path/deeper/index.vue 的深路径,只支持 /pages/path/index.vue 这样的浅路径,若要识别深路径需要使用分包 subpackages 进行处理。同时,在构建小程序代码时可能会因为 cache 而引发错误,尝试清除并重新打包即可。

另外,通过 >Volar: Select TypeScript Version 试过 Volar 的几个 Typescript Checker 的几个版本,在可用的版本中似乎都无法对 Pinia 的"组合式写法"很好的解析,会因为赋值过程中改变类型而报红,然而实际上代码是可以正常运行的。为了解决这个问题,目前只有忽略代码优雅性,将 state 变量类型设置为 any。

Tabbar

Taro 支持使用 React、Vue、或者小程序原生语法来编写小程序自定义 TabBar 组件,通过状态管理工具(Pinia)对 Tabbar 页的状态进行管理。

// @/store/tabbar.ts

import { ref } from 'vue';
import { defineStore } from 'pinia';

export const useTabbarStore = defineStore('tabbar', () => {
  const index:any = ref(0);
  return { index };
});
// @/custom-tab-bar/index.vue
// [script setup]

import Taro from '@tarojs/taro';
import { useTabbarStore } from '@/store/tabbar';

const store = useTabbarStore();
const selected = store.index;

function switchTab(index, url) {
  store.index = index;
  Taro.switchTab({ url });
}

// 余下省略...

样式补丁

虽然 Taro 在小程序的逻辑层实现了浏览器环境模拟,但样式部分仍受对应平台的约束。所以,作为开发者仍需要参考其平台指南,例如微信的小程序开发指南,只有基于了解才能更好的解决某些问题。例如页面高度占满屏:

<template>
  <view class='wrapper flex items-center justify-center'>
    <view class='box'>box</view>
  </view>
</template>

<style>
  .wrapper {height: 100%;}
</style>

在 H5 中效果正常,然而在小程序中 wrapper 高度将出现问题,原因是没定义 WXML 中 page 的高度,样式表部分修改后如下:

page {height: 100%;}
.wrapper {height: 100%;}

另外在我使用的 NutUI 4.0 版本中,其部分组件会出现样式问题,这也可能是 Tailwind 的样式初始化导致的。这类问题可自行优化,例如:

/* NutUI CSS Patch & Beauty */
.nut-avatar-round {overflow: hidden;}

.nut-short-password-wrapper {display: block;}
.nut-short-password--forget {align-items: center;}
.nut-short-password--forget .nut-icon {
  margin-right: 0.3rem;color: var(--info);
}

.nut-tabbar-safebottom {padding-top: 4px;}

至此,待续。