Taro + Vant-WeApp + Vue
Warning本文发布于 2023/07/18,内容可能已过时。
开始
小程序跨端除了只适用 Vue 的 Uniapp 外,还有京东的 Taro,支持 Vue/React,目前使用 WebPack 5 进行编译,后续会使用 Vite。Vant 是有赞的移动端为主的组件库,Vant-WeApp 是其中的微信小程序版 (也就是这个只能用在微信小程序中,h5 都不能)
初始化
需要先安装 Taro 的脚手架,然后创建模板。或是我摸出来的 Start
其中选择默认模板即可,同时由于模板的依赖有许多都过时了而导致编译失败,需要先升级 pnpm up --latest
Taro 的项目结构和内部 Vue 的写法主要是以小程序 <View/>
的为主,当然也可以设置成 HTML 的标签
配置
app.config.ts
是小程序的全局配置,/pages
下是页面路由,每个页面的 *.config.ts
是该页面的小程序配置。这些皮脂定义了路由页面 (全局)、窗口状态和样式等。可见文档:全局配置和页面配置
eslint
新建 Vue 项目当然得 extend @antfu 的配置)
然后在 .eslintrc
的 extends 添加 @antfu
就好了,pnpm eslint . --fix
tsconfig
基本没差什么,添加别名和导入 @vant 就需要添加:
使用 HTML 标签
其实实际上是可以使用 HTML 标签的,装个插件就行,它会将这些标签转译为小程序的标签
使用 unplugin-vue-components
还是来自 @antfu,有了这个就不用在导入自定义组件的时候都得手动 import 了
同时需要设置到 webpack 编译中:
记得将导出的类型文件加到 ignore 里:
路由
页面路由的写法虽然很奇怪,但小程序是这样的。第一个是文件夹名,第二个是 Vue 文件名,它似乎不能自动检测类似 index 这样的特殊命名。而且到编译后的开发者工具或是 h5 的 URL 也是这样的形式
约定来说,它主要是以文件夹作为页面路由的划分,每个页面下会有一个 *.config.ts
的页面配置文件
子路由和跳转
由于小程序是一个 SPA 应用,基本就只能在当前页切换。因此 pages 更像是对应的是主页的 tab page,而 subPages 是要跳转的路由页面,他们通常会放在 packages 文件夹下
编译配置
根目录下的 /config
文件夹是 Taro 的编译配置,文档可见:编译配置
基本不变就行了,只不过 eslint 可能会报错 process
的问题,就需要手动导入 const process = require('node:process')
添加路径别名和导入 @Vant:
其中,copy.patterns
是指将 node_modules 里 @vant 的组件 dist 目录复制到编译文件夹中,这是因为文档:
vant 组件中包含一些小程序原生文件的依赖,目前 Taro 没有对这些依赖进行分析
引用 Vant 组件
这需要手动在配置文件中导入具名组件 (像是 <van-button/>
),可以在全局导入,但有时候会引用冲突 (?) 导致有些组件不能在全局导入的时候共存,就需要在各自的 page 下 using 了
这里的地址取决于在编译配置中将组件复制的地址 (相对于编译后的 /dist/app.json
) 来说,当然可以写一个函数来简化:
这样子在 Vue 中就能直接使用组件,不用手动 import
只不过这种是属于使用 npm 包的方式,它需要在 /dist
下有 node_modules 和 packages.json,并在编译前在开发者工具中点构建 npm 才能使用
所以就多了一步 copy:
运行
pnpm dev
后,就能在微信开发者工具中导入 dist 目录来预览了
一定要禁用缓存 & 热重载不了
虽然 cli 会提示强烈建议开启缓存,但实测发现它会导致很多配置方面的问题
首先每次编译的时候,它默认都会将 /dist
删除,然后将存在某个地方的缓存与当前编译结果 diff (也许) 后复制过来。但对于微信开发者工具来说,由于项目根目录被清空了,它会直接报错:找不到 app.json 之类的,这时候就要让开发者工具重新编译…(它本来是可以热重载差异化编译的)
回到缓存问题,我发现实际上开了缓存后,修改 app.config.ts 之类的配置文件后,再次 pnpm 编译,dist/app.*
的内容实际上还是很早之前的,这时候例如添加页面、组件都并没有应用上,小程序那边就会报错:xx not found 之类问题…
使用 @ngify/http
请求库
@ngify/http 适配了微信小程序特殊的 wx.request
(也就是在小程序里是没有 XMLRequest 或是 fetch 的,得用它自己的请求库),并配合 RxJs 风格的处理
首先新建一个 src/service
文件夹专门用来处理请求,在 index.ts 中初始化设置为 wx 请求库:
然后在 app.ts 导入初始化
这样就可以新建一个请求类了:
函数将返回 Observable<T>
供以后续使用 RxJs 处理
其中要注意的是,由于微信小程序的限制,请求的只能是备案过的域名…