直击根源:vue项目微信小程序页面跳转web-view不刷新
背景
最近项目需要适配小程序,项目是使用了vue开发的网站,其中改造方式是,每个页面都使用小程序创建一个页面通过web-view来显示指定页面的。
在没有使用小程序时,路由跳转时,刷新页面等等,这个是很顺畅的,在使用了小程序之后,需要适配小程序的页面,比如后退到前一页,这个时候要刷新页面,于是遇到了小程序的一些特性。
问题描述
有两个页面:A=http://demo.com/#/A?code=12
,B=http://demo.com/#/B?index=2
A页面跳到B页面,B页面把一些处理后的结果以参数的形式传给A页面。
例如:B页面的使用了wx.navigateBack
(其它跳转函数同理),且url(http://demo.com/#/A?code=12&index=12
)以参数的形式传给了A页面,A页面在OnShow
方法里面重新设置了web-view的src地址,能保证正确,但是页面就是不刷新,且使用微信开发者工具,能看到src已经被改变了。
尝试解决
-
网上一些方法:比如先设置src为空字符串,然后再通过setTimeout设置src为期望的值,且要设置时间为60ms以上(玄学),这个方法之前我还真解决了一个问题,不过那个场景是:A是一个web-view页面,B是一个小程序页面,B返回A时,通过给A传递参数,设置src可以通过此方法正确显示,此方法但是没有解决A、B页面都是web-view的形式。
-
网上一些方法:在B页面先把A页面的src设置为空,然后再直接设置为需要的url,此方法依然对本问题无效
-
我把1、2两种方案结合也没有解决。
-
最小化正确原型
这个时候,我在思考这个页面到底能不能正常刷新,注意这个想法非常的重要:
我用了最小正确原型来先验证,能否正确得到期望,最小原型如下:
A的页面web-view src=
https://baidu.com
,然后打开看一下,可以正常显示页面,之后在B页面返回A页面时,给A页面传递了一个url,在A页面OnShow里面设置了A的src=https://www.qq.com
,结果页面刷新了,正确的显示了www.qq.com
页面,也就是说不需要什么settimeout。之后反复测试,同样的连接是不刷新的;设置为空是不刷新的。
这个时候,已经找到了可以正常刷新的条件,不是原链接、不是空,都可以刷新页面,那么问题来了,A页面的链接都已经变了,后面的参数变了,怎么还跟缓存了一样(同一个get链接,会被缓存起来的)。
-
再分析原始的A的链接
从http://demo.com/#/A?code=12
,变成了http://demo.com/#/A?code=12&index=12
,这个形式,改变够大了,但是还是缓存了,这个时候应该就是缓存策略问题了,毕竟以前解决ie浏览器时,我们通过添加url随机数就可以避免。注意到了吗?vue页面中使用了#作为路由判断的,而#在浏览器中是作为锚点使用的,是不是小程序对这个解析也有差别,认为是同一个页面,于是做了如下的测试:
http://demo.com/?code=12&index=12/#/A
结果,参数放到#之前,小程序果然刷新了,看来小程序对#就是按照同一个页面解析的,好了刷新的问题解决了,下来看看vue是否能正确识别参数
使用this.$route.query.index的值,成功取得了值。
最后
自此问题得以解决,总结如下:
- 网上的很多解决方法适用场景可能跟你的不一样;
- 黔驴技穷时,使用最小正确原型开始验证期望;
- 找到差异的地方,或者特殊的地方可能就是问题所在;
- 懂原理、机制能事半功倍快速解决问题
- 小程序还可以提升的更好,比如方案1真的有效,要不是之前第一版迁移方案我遇到过,我都觉得这个是开玩笑的方法