项目场景:
最近要使用uniapp开发微信小程序、字节小程序、安卓、IOS四端一体的项目,记录一下踩坑,持续更新...
问题一
描述:
有一个分页列表,列表中的每项数据被封装成了一个子组件。通过请求接口拿到数据渲染到页面。在小程序上无异常,但是在安卓APP上子组件并未渲染数据。
原因分析:
遇到这种情况后,先确认子组件是否收到父组件传递过来的数据。经调试发现,子组件确实是收到数据。然后猜测可能是异步请求和生命周期执行顺序导致的。就尝试不调用接口,先传静态数据到子组件,结果还是不渲染。然后仔细review了代码,发现这个列表的数据因为要做分页,结构处理成了二维JSON数组。遍历数据的时候,最外层遍历使用了template空标签来遍历。就猜测是不是这个标签导致的。然后把template标签替换成view标签。果然,数据成功渲染到页面。
解决方案:
使用 view 标签替换 template 标签作为循环体。
问题二(2022.6.24更新)
描述:
Nvue页面会把注释掉的CSS代码编译进项目,控制台会抛出异常或警告。
解决方案:
删除注释掉的代码。
问题三(2022.7.4更新)
描述:
业务场景大概是这样的,有A、B两个vue文件开发的页面,A是列表页,B是详情页,B页面由于功能需要,使用的Map组件,且页面底部有几个功能按钮使用了fixed布局固定显示在页面底部。在这个前提下,问题就出现了。在小程序端,由于微信小程序和字节小程序实现了同层渲染,不会出现Map组件覆盖在功能按钮上,但是在APP端,Map组件会作为原生组件渲染,而原生组件比普通的标签节点层级高,是不能调整的。
解决方案:
方案一:
使用cover-view标签来渲染底部功能按钮,cover-view标签可以覆盖在原生组件之上。但是这个解决方法不适用当前业务场景,因为样式比较复杂,需要用到cover-view和cover-image,还需要进行嵌套。但是在APP端,cover-view不支持嵌套。引来官方文档说明【App端vue页面 cover-view
、cover-image
中不支持嵌套其它组件,包括再次嵌套cover-view
,仅可覆盖video
、map
。】
方案二:
使用SubNvue解决,它是Vue页面的原生子窗体。使用nvue文件开发,这里就使用SubNvue来编写底部功能按钮页面,根据官方文档配置,即可实现。详细配置参考uniapp-SubNvue。这里要注意的是,SubNvue并不是支持全部的CSS样式,且不支持百分比布局,仅支持flex布局。要控制某个节点样式,需要使用class选择器,不能使用节点选择器。其他注意点参考介绍 | uni-app官网 (dcloud.io)
问题四(2022.7.4更新)
描述:
结合前面问题三的描述和业务场景,导致出现了一个新的问题。具体情况如下:由于底部功能按钮需要根据后端返回的数据来判断渲染,因此这里就需要B页面和SubNvue子窗体页面(后面统称为sub窗口)进行通讯,这里直接采用官方提供的uni.$emit()和uni.$on()方法来通讯,可以顺利接收到B页面传递过来的数据,然后根据数据在sub窗口进行业务逻辑判断并渲染按钮。目前来看一切正常,但是当我退出B页面,回到A页面之后,再进入B页面,sub窗口的节点并没有渲染(开始慌了)。经过调试发现,每进入一次B页面,就会创建一个sub窗口实例。没办法,继续仔细阅读官方文档,发现只有隐藏sub窗口的方法。在社区搜索发现2年前已经有开发者反馈过这个问题,无果。此处手动@uniapp官方一万遍!没办法,代码还是要继续写...
解决方案:
注意:该方法并没有解决重复创建sub窗口实例的问题,想解决这个问题的小伙伴就不用继续看了。这个方案只是解决从B页面退出后再次进入B页面后,sub窗口的按钮没有渲染的问题。
通过上面的问题描述可以知道,B页面使用uni.$emit()把数据传递给sub窗口,然后在sub窗口用uni.$on()监听传递过来的数据。这种方式在频繁退出进入B页面后,会出现sub窗口节点不渲染的问题。然后我在sub窗口使用一个show变量,用v-if的方式来控制整个sub窗口节点,再用watch来监听数据变化,并用新数据去替换旧数据,本以为就这样可以解决了。但是并没有,问题还是会复现。且经过调试发现,watch钩子接收到的数据有时候是undefined。可能是方法执行顺序的问题,没有想明白。然后,彻底放弃uni.$emit()和uni.$on()的方式通讯,使用uni.setStorageSync()来实现。在B页面拿到页面数据后,用uni.setStorageSync()把数据存储起来,然后sub窗口在onReady()钩子使用uni.getStorageSync()读取数据。在B页面onUnload()钩子清除缓存的数据,在sub窗口页面onUnload()钩子重置数据。至此,频繁退出进入B页面,可以正确渲染对应的功能按钮,问题解决!