uniapp踩坑记录
最近公司在用 mPaaS 搞小程序,uniapp 模板那一套,记录一下使用中的一些踩坑点。
说明:
文章中提到的小程序 mini program 统一简称 MP。
运行小程序 props 传值,对象方法丢失
uniapp 的 prop 传递的变量为对象时,对象内部含有函数属性,该函数属性会直接被删除。
了解更多,详见
运行 H5 时 v-if、v-for 值更细渲染异常
mPaaS + uniapp 框架下,会复现。
解决方法:
- 通过条件编译,H5 时用 html5 标签
- 有 v-if、v-for 的地方直接 div 代替 view,运行小程序时,div 会自动编译为 view,详见
运行小程序 image 标签@error 事件直接替换 src 值,渲染无效
只能通过条件渲染,如下:
1 | <template> |
小程序无法通过 document 获取 DOM 节点信息
如果有获取元素距离顶部的间距这样一个场景,小程序无法通过 document 来获取相关信息,需要用到uni.createSelectorQuery()
。用法以下几点需要注意:
- 使用 uni.createSelectorQuery() 需要在生命周期 mounted 后进行调用。
- 默认需要使用到 selectorQuery.in(this) 方法,因为 this,如需公共写法,只能 Vue 的 mixins 混入写法,可挂载到全局。
- 支付宝小程序不支持 in(component),使用无效果
兼容实现方案:
1 | getRect(selector, all) { |
更多,详见
顶部搜索下面的吸顶总会有间距
解决方案:吸顶时,外层元素增加padding-top
,可以根据需求设置背景色;同时,下方加个占位高度的元素,防止吸顶时,下面的开头部分内容被遮住。
onHide()和 onUnload()触发时机
onHide()触发的场景
- 导航页 1 => 导航页 2,会触发导航页 1 onHide()
- ? 导航页 => 子页面,会触导航页 onHide()
- 子页面 1 => 子页面 2,会触发子页面 1 onHide()
onUnload 触发的场景
- 子页面 2 返回子页面 1,会触发子页面 2 onUnload()
- 子页面返回导航页,会触发子页面 onUnload()
注意:
- 导航页之间的切换不会触发 onUnload()
- 页面 2 返回到(页面 1 或者导航页)时,页面 2 只会触发 onUnload(),并不会触发 onHide()
页面路由跳转
使用 uni.navigateTo(OBJECT)时,url 可以是相对路径,也可以是绝对路径,注意文件目录层级关系。
v-if、v-show 编译到小程序中的坑
v-if
编译的时候,小程序那边成了 display:none\block 控制,并不是 DOM 的创建和移除。
使用定位会造成盒子错乱,距离尺寸不好把控,在使用 v-if 的时候尽量多套一个盒子去适配好一点。
v-show
编译的时候,小程序那边也成了 display:none\block 控制,但是多了一个 CSS 权重问题,可能会照成控制盒子不生效问题,尽量避免使用。
总结:
在使用自定义组件 tab 选项卡时会有使用 v-if/v-show 的时候需要多套一个盒子,来避免造成 css 的样式在其他端(H5、mini program)不兼容等问题。
图片错误展示占位图兼容 H5/MP
需要通过 import 引入展位图,data 赋值,然后用 v-if 判断展示展位图。
禁止 ios 橡皮筋效果
可以使用页面的 onPageScroll
事件来禁止 iOS 上的橡皮筋效果。
在页面的 onLoad
生命周期函数中,判断当前设备是否是 iOS,并将 disableScroll
属性设置为 true
。
1 | <script> |
在页面的 onUnload
生命周期函数中,将 disableScroll
属性设置为 false
。
1 | <script> |
在页面中监听 onPageScroll
事件,在滚动时判断是否需要禁用橡皮筋效果。
1 | <script> |
这样,在 iOS 上滚动页面时就不会出现橡皮筋效果了。需要注意的是,由于 Uniapp 的渲染机制可能会有不同,上述方案可能不适用于所有情况。