前言
最近有点闲, 想起关注已久的 mpvue 写小程序, 所以稍微肝了半个多月写了个 github 版的微信小程序, 已上线. 现在总结一下遇到的坑.
扫码体验,
项目地址, https://github.com/cheesekun/wx-github
mina 坑
scroll-view 高度
可滚动视图区域.
使用竖向滚动时, 需要给 < scroll-view/> 一个固定高度, 通过 WXSS 设置 height.
小程序提供的 scroll-view 组件, 想让他能滚动, 就要给他提供一个固定的高度.
我们一般需求是, 上一块区域固定, 下一块区域可滚动, 我的处理方法是, 拿到机型的可视高度, 减去上一块固定区域的高度, 动态赋值 scroll-view 最终高度.
- // 以 search 页为例
- // 滚动区域高度 = 总高度 - 搜索框高度 - tabs 高度
- onLoad () {
- wx.getSystemInfo({
- success: (res) => {
- this.height = res.windowHeight // 获取机型可视高度
- }
- })
- let query = wx.createSelectorQuery()
- // 选择 id
- query.select('#search').boundingClientRect()
- query.exec(res => {
- let searchH = res[0].height // 获取 search 框高度
- this.height = this.height - searchH - this.tabsH
- })
- }
复制代码
坑点:
wx.createSelectorQuery()
获取不了 display: none 的元素高度.
我的解决方法是: 在 trending 页获取到 tabs 组件的高度, 再存放到 vuex 中, 给 search 页使用
生命周期 (同一 page 携带不同参数)
小程序生命周期 https://segmentfault.com/a/1190000010874608
当我们从一个页面进入页面时, 我们一般在 onLoad 进行初始数据的获取,
从页面返回到页面时, 若两个页面是不同的 page, 如为 page/info,
为 page/repo, 那没问题,页面 unOnLoad,页面 onShow.
但是若为 page/info?user=a,为 page/info?user=b, 那 gg 了, 从页面返回到页面, 页面的数据会变成页面的数据
为了避免这种情况, 我一开始使用 onShow 代替 onLoad, 也就是在 onShow 的时候获取页面的初始数据. 但是这个情况就有点可怕了, 我们知道 onShow 很多情况都会触发到, 切换前后台, 从一个页面返回到另一个, 都会触发 onShow, 这就导致会触发很多不必要的请求, 而且用户体验极差.
可我很多需求就是类似从为 page/info?user=a 到为 page/info?user=b, 因此曲线救国想出用 vuex 维护有相关需求页面的路由栈.
页面 onLoad 的时候, 推入 query 参数到栈中, onShow 时, 若当前页面的参数和栈中最后一个元素相同, 则不重新加载数据. 当页面被销毁, 则在 onUnload 中把相应的页面栈推出. 这样就可以避免很多无谓的 onShow 请求.
- onLoad () {
- this.reset()
- const options = getQuery()
- user = options.login
- // vuex
- this.reposStack.push(options)
- this.getRepos()
- },
- onShow () {
- const options = getQuery()
- // vuex
- let reposStack = JSON.parse(JSON.stringify(this.reposStack))
- let len = reposStack.length
- let endStack = reposStack[len - 1]
- if (JSON.stringify(endStack) === JSON.stringify(options)) {
- return
- }
- this.reset()
- user = options.login
- this.getRepos()
- },
- onUnload () {
- // vuex
- this.reposStack.slice(0, -1)
- }
复制代码
mpvue 坑
query 参数
mpvue 可以通过
this.$root.$mp.query
在所有页面的组件内获取路径参数.
如果以 mina 来说的话, 我们是通过在生命周期 onLoad(options), 拿到 options 上携带的路径参数, mpvue 提供了
this.$root.$mp.query
, 我们可以所有生命周期上使用.
但是我们知道, 当我们从当前页返回到上一页时, 上一页并不会执行 onLoad(),
假设当前页和上一页是同个 page, 只是携带参数不同的话, 此时回退到上一页,
上一页的
this.$root.$mp.query
不会变成自己的 query, 还是会变成当前页的 query
举例:page/info?a=1 => page/info?b=2
当我从返回到时,的
this.$root.$mp.query
会变成 {b:2}
我猜 mpvue 的
this.$root.$mp.query
是通过 onLoad(options) 获取到 options, 再赋值. 但是遇到小程序页面返回不会执行 onLoad
为了避免麻烦, 我直接使用了小程序的 api getCurrentPages(), 获取路由栈中最后一个路由的参数
getCurrentPages() 函数用于获取当前页面栈的实例, 以数组形式按栈的顺序给出, 第一个元素为首页, 最后一个元素为当前页面.
- /**
- * 获取当前路径参数
- * 不用 mpvue 提供的 this.$root.$mp.query
- * 因为其进入同一页面, 参数不会变化
- */
- export function getQuery () {
- /* 获取当前路由栈数组 */
- const pages = getCurrentPages()
- const currentPage = pages[pages.length - 1]
- const options = currentPage.options
- return options
- }
复制代码
后记
前面几个问题是我初次使用 mpvue 开发小程序遇到的最大的坑了吧.(好久没有写东西了, 写得好烂.) 不过确实使用 mpvue 开发小程序, 能组件化, 支持 npm, 比原生开发舒服很多. 体验还是很好的. 小程序现在是真的太火了. 感觉是个前端都要去玩一下. 再次推一下项目地址, 有兴趣的朋友可以参考一下. https://github.com/cheesekun/wx-github
来源: https://juejin.im/post/5b7bd9ea51882542d23a0e3d