微信小程序开发的相关问题
最近开发了一款小程序,主要是展示近期的一些最新、最火的电影以及相关信息,该小程序由首页、列表、详情、评论、视频这几个页面构成。虽说开发过程还算顺畅,但在其中,也遇到一些难搞的问题,为方便日后参考,因此把部分问题列举于此:
一、请求不在以下 request 合法域名列表中
如果你的小程序使用了服务端接口,当你在本地开发时,可能会遇到如下错误:

出现这种情况,是因为没在后台设置request合法域名。如果你只是本地开发,用于某些测试,你可以在 微信web开发者工具 中的 设置 -> 项目设置 里作如下设置:

但倘若你要发布到线上,那你得登录微信公众平台的后台,设置相关服务器域名。如果你的小程序需要调用多个接口,你也可进行设置多个。

二、网络接口必须是https
对于小程序接口,要是在从前,你可以使用 http 协议,也可以用 https 协议。但现在,你的网络请求接口协议必须是https。
但要注意,服务器域名修改后,一定要在 微信web开发者工具-清缓存、重新编译。
或许有的时候这样做并不管用,那么,你得重启 微信web开发者工具。
三、配置文件不生效
我们知道,每个小程序的根目录都有一个 app.json
文件,它用于对该程序的全局配置(标题栏文字、界面风格、底部tab)。但为了保证某个页面能够单独设置相关属性,小程序规定,可以给每个页面目录都配置了一个 *.json
文件。
但要注意的是,每个目录下的 *.json
文件,一定要与当前目录文件同名。比如,pages/comment
目录里,必须是 comment.json
。否者,json文件配置不会生效。
四、video元素无法播放
因为是电影相关的小程序,所以少不了视频界面。其中,使用了小程序提供的 video
元素用于播放电影预告片。
当在微信开发者工具预览效果时,却在控制台出现了如下错误:

因为是引用的是第三方视频资源,最初我以为是该远程视频服务器加了防盗链。于是,我上传了一段视频到我的服务器,再在小程序里引用它,嗯,视频可以正常播放了。接着,再扫码真机测试,但却出现如下界面:

视频区域一片漆黑,没有播放按钮,没有加载,什么情况?
搜索了各方资料,有说是基础库问题,有说是手机系统问题,还有说是视频格式问题,时间一分一秒过去,最后还是无果。
通过上面的截图,我一开始是把视频内容放在页面底部(页面超过一屏,即视频内容在第一屏之外),后来我又在页面顶部放一个相同的视频区,再真机扫码测试。
结果,页面顶部的视频可以播放,但底部却还是一片漆黑。难道跟布局有关?于是,在公共样式里看到这么一行代码:
/* app.wxss */ |
尝试把它删除,在扫码测试,结果底部视频也能正常播放了。因此,如果设置了以上样式,解决方法就要把视频区放在第一屏中,或者,直接删除该样式。解决后截图如下:

五、iOS页面滑动卡顿
本以为小程序在 iOS 和 android 系统上表现一致,但当用iOS扫码测试时,发现在滑动页面时很不流畅,即手机滑动一段距离,页面只是移动一段距离,有时甚至不会移动。
一开始以为是列表页没有使用 scroll-view
组件原因所致,但很快发现详情页也出现滑动卡顿,要知道详情页并不适用 scroll-view
组件。所以,应该不是组件的问题。
由于iOS测试的是我线上的版本,当我再用iOS测试本地开发版本(该版本新增并修改了一些内容)时,列表页和详情页,都能顺畅滚动。
对比这两版代码,在样式上发现线上(旧)版本多了这些样式:
/* app.wxss */ |
尝试在本地开发版本加入上面的样式,再iOS扫码测试,结果滑动页面都变的卡顿起来了。解决方案,还是把类似样式删除。
六、wx.pageScrollTo 不生效
微信小程序提供了 wx.pageScrollTo(OBJECT)
方法,它可以将页面滚动到指定位置。
当进入到一个列表页,并且你希望页面滚动到某个位置时,你可以用到该方法。但当列表页面涉及到ajax请求数据列表时,即便你把该方法放在请求回调中,页面也不会滚动到指定位置。如:
wx.request({ |
猜测可能与页面渲染速度有关,于是设置一个延时执行页面滚动方法,问题便得到解决。
setTimeout(() => {wx.pageScrollTo({scrollTop: 1000 });}, 200); |
七、循环警告
当在小程序里循环渲染一组数据时,可能在控制台出现如下警告:

之所以这样是因为可能会出现动态列表、但这些列表项又得保存对应的特征和状态,并且为了提高渲染性能。因此,你需要使用 wx:key
来指定列表中每项的唯一标识符。
当渲染的数组项只包含本身时,你可以在 wx:key 上使用保留关键词 *this
,即:
<view class="item" wx:for="{{list}}" wx:key="{{*this}}"></view> |
当渲染的数组项为复合属性时,你可以在 wx:key 上使用每项对应的某个属性(假设每项包含 name 属性),比如:
<view class="item" wx:for="{{list}}" wx:key="{{item.name}}"></view> |
八、多重循环
如果数据涉及多重嵌套,如:
... |
那么在 wxml 中,可以这样来循环出 type:
<view class="item" wx:for="{{list}}" wx:key="{{item.name}}"> |
九、<text>
与 </text>
之间的空白与视图关系
借上面的数据和试图,当 text
组件里的 <text>
和 </text>
之间有空格,或者没空格时,会呈现出不同的试图,见对比(这里只展示text
代码),为了保证页面在手机屏幕下,示例代码块不折行,这里代码也使用的图片:
下图分别展示 text
组件一行、两行、三行的情况:

可以看到,当 text
组件不换行时,视图中循环后的两个 text
处在同一行。而当 text
组件换成两行时,视图中循环后的两个 text
各占同一行。当 text
组件换成三行时,视图中循环后的两个 text
前面有一个空白行。
十、图片路径
要在界面展示图片一般有两种形式,即 标签引入 或者 标签背景。
针对 标签引入,小程序定义了 image
组件,该组件可以引入本地图片,也能引入远程服务器图片。
<image src="pic.png"></image> |
上面两种路径写法,都能正常的显示图片。
但对于 标签背景 形式,倘若使用本地图片,如:
<view class="box"></view> |
则组件的背景图不会显示,在控制台将看到以下错误:

即WXSS文件无法读取本地图片,我们得把它替换成远程服务图片(绝对路径),这样,背景图片才能正常显示。
但如果你非要使用本地图片,也不是不可以。只是你得先将本地图片转换为 base64,再引入到背景样式中,这样,也能正常显示。
十一、事件对象里 currentTarget 和 target
和JavaScript事件一样,小程序里事件函数带有一个 event 参数,它包含一组信息。
值得注意的是,event对象里的 currentTarget 和 target 属性。其中,target 为 触发事件的源组件,而 currentTarget 为事件绑定的当前组件,这两者需要区别。
在处理组件前,我们会在组件上加 data-*
属性,而在事件中,再通过 event 参数里 currentTarget(或者target) 的 dataset 属性读取相应的值。
十二、canvas 等原生组件层级最高
通过官网资料,map、video、canvas、textarea等原生组件层级最高,无论其他组件设置多大的 z-index,也不能覆盖在原生组件之上。
但迫于一些特殊需求,我们需要在这些原生组件上覆盖一些其他组件(比如map上的操作按钮、canvas上的提示弹层),那么有没有方法实现呢?
答案是肯定的。经过尝试,发现目前主要有四种方法,总结如下:
- 虽然普通组件不能覆盖原生组件,但是原生组件之间却有层级关系,根据渲染效果,后插入的原生组件层级更高。因此,可以考虑用后插入的原生组件覆盖之前的。
- 利用原生组件的控件,比如 map 的 controls。
- 在普通组件覆盖原生组件时,可以先暂时把原生组件隐藏。该方法在 Android 上没问题,但 iOS 却发现 canvas 组件不会被隐藏,仍然覆盖在最上层。
- 使用
cover-view
组件,它是因为原生组件的层级问题而专门定义的组件。所以,基础库 1.4.0 才开始支持,低版本需注意作兼容处理。