2
赶上小程序的热潮,公司项目肯定也要跟一波风。私以为小程序就应该一两个页面,简简单单,结果我们第一个版本就来了十几个页面,三十个接口。。。
因为习惯了用vue,所以为了快速上手,决定采用mpvue,直接按照官方文档很容易把框架搭好,就只介绍一下遇到的一些问题

1、mpvue-entry

原来的写法是,每个页面都有一个main.js的配置文件,这样文件数量就很大,为了更接近vue的写法,一个页面一个*.vue文件,引入了mpvue-entry

mpvue-entry:集中式页面配置,自动生成各页面的入口文件,优化目录结构
// webpack.base.conf.js
...
var MpvueEntry = require('mpvue-entry')
module.exports = {
    entry: MpvueEntry.getEntry('c/pages.js'),
    ...
}
// pages.js
module.exports = [{
    path: 'pages/home'
}, {
    path: 'pages/post'
}]

2、自定义导航栏

  • 无法部分配置,要么全部用原生,要么全部改自定义
  • mpvue引入了postcss-pxtorpx,用于将 px 单位转换成微信小程序特有的单位 rpx,但导航栏的高度是固定的,所以我把这个插件去掉了,固定的高度用px,自适应的用rpx
  • 需要适配iphone/android/iphoneX,参考高适应性的自定义导航栏开发思路
题外话,以前固定导航栏,总是对导航栏设置position:fixed;后再将主体部分的内容使用padding-topmargin-top来留出导航栏的高度,避免被遮挡。这样造成的问题是,每个页面都要手动设置,而且还要根据机型来适配,很繁琐。
这次终于学到一个小技巧,在导航栏组件里添加一个placeholder,高度跟随导航栏的高度,position不要设置为固定,就可以把位置给留出来了
<header>
    <div class="navigation-placeholder" :style="{
        height: statusBarHeight + titleBarHeight + 'px'
    }"></div> // 这里就是用来占位的
    <div class="navigation-container" :style="{
        backgroundColor: backgroundColor
    }">
        <div class="status-bar" :style="{height: statusBarHeight + 'px'}"></div>
        <div class="navigation-title" :style="{
            height: titleBarHeight + 'px',
            lineHeight: titleBarHeight + 'px'
        }">
            <span
                v-if="back"
                class="back-icon"
                @click="onBack"
            >
                <img src="../assets/images/back.png" alt="">
            </span>
            <p
                v-if="title"
                class="title"
                :style="{ fontSize: textSize + 'px', color: textColor, textAlign: align }"
            >{{ title }}</p>
        </div>
    </div>
</header>

3、底部固定,弹窗滚动

弹窗简直是设计师美眉的秘密武器,美其名曰,让设计看起来更轻,好吧,开发们就要面对两个问题:
1、弹出收起的动画要流畅;
2、弹窗弹出来的时候,底部要保持在原来的位置上,并且不能随弹窗内容的滚动而滚动

  • 第一个问题,建议不要使用小程序的createAnimation,看起来好像也是用的transform,但效果比起直接手动用transform来控制还是要差一些
transition: transform .3s ease;
transform: translateZ(0) translateY(20px);
  • 第二个问题折腾得就比较久了。

a、直接对底部内容设置position:fixed; overflow:hidden;页面肯定是会回到顶部的;
b、小程序有一个catchtouchmove=true的属性,相当于touchmove.stop="stopTouch",stopTouch为一个空函数,就是阻止touch事件冒泡发生,如果弹窗内容是固定的,在弹窗上加这个属性,可以很完美地解决问题,但如果弹窗内容是个需要滚动的列表,你会发现也滚动不了了;
c、对b的问题,貌似可以用scroll-view的属性,但因为scroll-viewvideo组件支持不好,所以没有研究就直接放弃了;
d、完美地解决方案:刚开始我的弹窗结构是这样的:

<div class="dialog-mask" touchmove.stop="stopTouch">
    <div class="dialog-content"></div>
</div>

然后改成了这样:

<div class="dialog-container">
    <div class="dialog-mask" @touchmove.stop="stopTouch"></div>
    <div class="dialog-content"></div>
</div>

将阻止冒泡设置在了mask层,不让其影响到内容层,虽然有一些奇怪,但的确这个时候内容层的滚动不会再引起底部内容滚动了,误打误撞解决了这个问题。

4、slot支持不好

最遗憾的就是mpvueslot的支持竟然不如小程序原生,不仅不支持具名slot,对仅有的一个slot里竟然还不能添加动态变量,在捶胸顿足中迫不得已放弃。

5、videotextarea等客户端原生组件层级最高

很容易出现一个尴尬的情况,滚动列表的时候,视频竟然浮到了导航栏上方耀武扬威,还有,点击弹窗遮罩本应该关闭弹窗,结果却点到了底部的textarea组件。
解决方法也很简单,视频就用一张图片代替,播放的时候替换为视频,textarea在弹窗出现的时候disabled=true

6、webview自动全屏铺满

webview不能像iframe一样设置宽高样式

7、背景图片不能使用本地图片

图标转成base64,其余的使用<image />

8、navigateBack不能传参数

storage或者vuex搭配用起来~

9、页面卸载后数据没有初始化

这简直是一个难以置信的问题,某个页面已经卸载了,下次再次进入,一些data值竟然还保持在之前的状态,比如弹窗依然还弹起来的,最好在onUnload函数里处理一下

10、无过滤器,不能使用函数设置styleclass

这个就尽量规避吧,毕竟路不止一条,此路不通,换一条照样走。


bottle_
259 声望22 粉丝

好好学习,好好生活,好好工作