小程序出来那么久一直没有深入的开发, 这次借着公司要做小程序, 深入探索了一番, 结果挖坑无数, 当然, 仅限挖坑, 并没有填完. 哈哈, 就先 mark 一下.
因为公司业务需求, 这次小程序用的是 mpvue + typescript 进行开发.
mpvue 相关的坑
关于 input 问题
因为设计想把输入框的交互做成这个样子:
那用原生的输入框是满足不了的, 只能自己写组件咯. 那么就用 vue 的方式写了个组件, 结果发现, mpvue 关于 input 的问题还真不少.
input 用 v-modal 输入时候闪烁
组件嵌套 slot 有问题
input 不支持: type 和 v-modal
slot 等标签不支持添加 class, 无法编译成 wxss
嵌套组件, props 有问题
修改 slot 时, 不能热更新, 只能重新 NPM run dev
这是 GitHub 上相关的 issue:
inout 闪烁 issue
嵌套组件 slot 问题 11
嵌套组件 slot 问题 222
关于这个问题, 试了上述的解决方法, 但没有很好的解决 (摔). 所以, 自己用原生的方式重新撸了个组件.
小程序相关的坑
原生组件 canvas 问题
因为公司因为, 小程序里有不少的图表数据需要展现, 自然就是需要用到 cavas, 而 canvas 是属于原生组件, 它的 z-index 无限大, 一出现有弹窗内容需要把它覆盖就 gg.
实际上是能解决的, 只要使用 cover-view 当做遮罩层 (一开始我还以为, 需要把 cover-view 嵌套到原生组件的节点里), 把弹窗内容一并放入 cover-view 里, 但是很鸡肋的是, cover-view 里面包含的节点问题, 以及一些样式问题是没办法实现. 如果是弹窗内容很酷炫的话, 那我只能建议让设计改设计稿.
- <view>
- <canvas canvas-id="test"></canvas>
- // 这是一个遮罩层, 为了覆盖住原生组件 ( 1.9.0 及以上才支持 )
- <cover-view>
这是一个遮罩层 balabala
- </cover-view>
- // 官方给的 demo
- <video>
- <cover-view>
这里也可以覆盖 video 里的内容
- </cover-view>
- </video>
- <view>
下面是我遇到的相关 bug:
文本都要套上 cover-view 标签, 不然排版错误.
cover-view 里的内容不支持设置渐变, 阴影等样式.
自定义组件嵌套 cover-view 时, 自定义组件的 slot 及其父节点暂不支持通过 wx:if 控制显隐, 否则会导致 cover-view 不显示
canvas 不能放在可滚动的列表里, 在页面滑动时, 在真机效果下, canvas 不能很好的跟着滚动, 会出现刚开始滚动不动, 再滚动就会卡着突然消失的非常糟糕的效果
cover-image 不支持 bindtouchstart 等 touch 事件
总的来说, 小程序的原生组件问题还是很多的, 具体的实现都要在真机上测试才能看出各种问题.
使用 echart-for-wx 的坑
解决弹窗覆盖 canvas 的问题, 同样的是用上面的方法
解决方法: echart 使用 cover-view 是要在节点 ec-canvas 后面添加, 通过样式控制 cover-view 的对应位置
- <ec-canvas class="canvas" id="mychart-dom-line" canvas-id="mychart-line"
- :ec="ecLine">
- </ec-canvas>
- <cover-view class="cover-view">
- cover-vdddddddddddddiew
- </cover-view>
echart 在使用 rpx 为单位时, 出现机型适配问题
echart 在不同机型上适配问题, 使用单位为 px 时, 适配是没问题的, 但是使用 rpx 时, 就会出现小机型适配问题, 而使用 mpvue 的话, 单位为 px 会转换成 rpx, 就会出现如下问题:
实际效果:
预期效果:
解决方法:
在 mpvue 里, 使用内联样式 (内联样式不会把 px 转成 rpx), 最好只固定高 emmmm.... 结果发现, 大屏小屏手机下都会有适配问题, 所以不能单纯的用内联样式写死 px 的大小 (在 GitHub 上提了个 issue, 至今未回, 怕死石沉大海啦)
canvas 生成图片适配问题
因为不同手机大小以及其设备像素比 devicePixelRatio 不一致, 再来小程序还出了自己的单位 rpx, 所以如果生成 canvas 是固定写死其宽高, 这样是用问题的.
基本算法是:
canvas 绘制使用的是 px 单位, 但不同设备的 px 是需要换算的, 所以在组件中统一使用 rpx 单位, 这里就涉及到单位怎么换算问题. 通过 wx.getSystemInfoSync 获取设备屏幕尺寸, 从而得到比例, 进而做转换, 代码如下:
- const sysInfo = wx.getSystemInfoSync();
- const screenWidth = sysInfo.screenWidth;
- this.factor = screenWidth / 750; // 获取比例
- function toPx(rpx) { // rpx 转 px
- return rpx * this.factor;
- }
- function toRpx(px) { // px 转 rpx
- return px / this.factor;
- },
但我知道大家都很懒, 有轮子干嘛不用
实在不想算, 可以用现成的轮子小程序 canvas 生成图片 https://GitHub.com/Kujiale-Mobile/Painter
再来就是, canvas 转图片的问题
需要使用 canvasToTempFile 方法, 因为 canvas 节点一定要存在才能获取到 canvas 的上下文进行绘图, 所以只能把 canvas 放到页面可视区域之外. 而且转换成图片时, 要加个神奇的 setTimeout 的延时. 最小延时为 300ms, 再小就不管用了.(为什么, 我也不知道, o(╥﹏╥)o)
最后
这只是一点挖坑心得记录而已, 还有更多的坑需要继续发掘.
来源: https://juejin.im/post/5ba20c0be51d450e4967e0e9