TUIKit是腾讯的一个基于 Chat SDK 的 UI 组件库,目前支持 H5、小程序、uni-app,但并没有对 Taro 的支持。
由于我的项目是基于 Taro 的,因此我先要把它 uni-app 的版本迁移到 Taro 上去。
准备工作
将chat-uikit-uniapp克隆到本地,把里面原有的 .git 和 sample 删掉,自己初始化一个 git。
当然,在初始化 git 之前,可以把项目名先改成chat-uikit-taro
,毕竟 Taro 才是主体目标嘛。
1 | git clone https://github.com/TencentCloud/chat-uikit-uniapp.git |
修改库本身
Taro
把所有uni.
替换成Taro.
,注意有些带有-uni.png
的要手动排除掉。
由于 Taro 需要手动import
,在所有vue
文件的script
部分统一补上。
1 | <script setup lang="ts"> |
以及
1 | <script lang="ts" setup> |
生命周期
Taro 的生命周期钩子和 uni-app 也不一样,需要找到并替换掉,搜索@dcloudio/uni-app
,便可找到所有钩子的引入位置,所有钩子替换完后再把@dcloudio/uni-app
替换成@tarojs/taro
。注意要把不相关的选项手动排除掉(如emit
)。
onLoad
——useLoad
onUnload
——useUnload
onReady
——useReady
onHide
——useDidHide
事件
Taro 的事件处理和 uni-app 也不一样,做以下的替换:
$on
——eventCenter.on
$off
——eventCenter.off
$emit
——eventCenter.trigger
编译宏
Taro 的编译宏和 uni-app 并不相同。
先搜索#ifdef
。
adapter-vue.ts
中,直接把vue
指定为vue3
版本。
1 | let vueVersion = 3; |
entry-chat-only.ts
中,做出以下的修改:
1 | ... |
再搜索#ifndef
。
server.ts
中,将locale
相关代码注释掉。
1 | ... |
去除 ts 里对 vue 的引入
Taro 的 ts 文件里不能直接引入 vue 文件,不然会把编译好的字符串全部直出到页面上。
TUIKit/index.ts
中:
1 | import { genTestUserSig } from "./debug"; |
重命名重名组件
TUIKit
有一个Icon.vue
的组件,很容易跟项目所用的组件库里的组件重名,要给它换个名称。
在所有vue
文件中搜索Icon.vue
,替换成IconImage.vue
,同时将import Icon from
替换成import IconImage from
,再把<Icon
替换成<IconImage
,把components/common
目录下的Icon.vue
重命名为IconImage.vue
。
调整样式
搜索:not(not)
相关样式,把它们全部注释掉。
Taro 不支持局部样式,把所有的scoped
去除。
在TUIKit/assets/styles/common.scss
中,把最顶上的样式重置删除(不是注释,直接删)。
1 | // body, div, ul, ol, dt, dd, li, dl, h1, h2, h3, h4, p { |
解决样式覆盖冲突
上一步把scoped
去除后,样式就变成了全局样式,可能会产生样式污染的问题,最常见的是.btn
会污染项目里原本就有的.btn
。
将.btn
改个名吧,统一替换成.tui-btn
,注意要只改样式和html
,不要影响到其他逻辑里的btn
。
替换导航路径
下面会写到 Taro 的页面跟 uni-app 并不相同,因此导航的路径也会不同。
在所有文件中搜索/TUIKit/components/
,按以下规则进行替换:
/TUIKit/components/TUIChat/video-play
——/TUIKit/pages/TUIChat-video-play/TUIChat-video-play
/TUIKit/components/TUIChat/index
——/TUIKit/pages/TUIChat/TUIChat
/TUIKit/components/TUIContact/index
——/TUIKit/pages/TUIContact/TUIContact
/TUIKit/components/TUIConversation/index
——/TUIKit/pages/TUIConversation/TUIConversation
/TUIKit/components/TUIGroup/index
——/TUIKit/pages/TUIGroup/TUIGroup
/TUIKit/components/TUISearch/index
——/TUIKit/pages/TUISearch/TUISearch
替换变量
将所有isUniFrameWork
替换成isTaroFrameWork
。
在TUIKit/utils/env.ts
中,做以下的修改:
1 | import Taro from "@tarojs/taro"; |
解决滚动失效问题
目前 Taro 貌似不支持通过设置scroll-view
的scroll-top
来滚动页面,在TUIKit/components/TUIChat/message-list/index.vue
的末尾加上如下的代码:
1 | watch( |
给项目集成库
主要参考官方文档来一步步做:https://cloud.tencent.com/document/product/269/64506
项目的package.json
里添加以下依赖:
1 | { |
将TUIKit
目录整个复制到项目的src
目录下。
将node_modules
里的@tencentcloud/tui-customer-service-plugin
的tui-customer-service-plugin
目录复制到TUIKit
目录下。
在tui-customer-service-plugin/componentsmessage-product-card
中,做出以下修改:
1 | <script lang="ts"> |
在app.ts
中,进行im
的登录操作。
1 | const tuiConfig = { |
由于 Taro 的单个页面下只支持一个vue
文件,我们不能直接用TUIKit/components
里的组件作为页面。
新建一个TUIKit/pages
目录,再将所有组件对应的目录、以及它下面的vue
文件和ts
配置也创建下。
1 | mkdir src/TUIKit/pages |
所有的config.ts
文件里添加统一的配置。
1 | export default definePageConfig({ |
每个vue
文件里引入components
目录下对应的组件(以 TUIChat.vue 为例)
1 | <script lang="ts" setup> |
最后在app.config.ts
里添加对应的分包(要看项目,不一定加所有的页面)。
1 | export default defineAppConfig({ |
优化主包体积过大问题
可以用webpack-bundle-analyzer
插件来直观地查看依赖大小,以进一步地优化体积。
1 | npm i webpack-bundle-analyzer -D |
config/prod.ts
中这么配置:
1 | module.exports = { |
这样就能很直观地看到TUIKit
相关的依赖足足占了 1 个多M
,WTF!
如果你小程序主包的页面很多且体积很大,就把除了tab
页以外的页面全放到分包里吧。
项目里有echarts
这个大头的话,把它也放到分包里吧。
其他优化
可以根据项目需求来进一步地改进和优化TUIKit/components
里的组件。
最后
费了一番功夫,总算迁移完成。
只能说 TX 你做得好啊,你做的好。