最近又遇到了微信小程序开发的需求,但实在是不想再用微信那套自己的开发框架,于是转头开始尝试小程序方面多端统一开发的解决方案。
在这方面比较成熟的有 uni-app、APICloud、kbone 和 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。
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;}
至此,待续。