前言
这段时间给公司开发了一个售后小程序,这也是笔友第一次开发「微信小程序」,之前主要做的是各种管理后台的项目,「微信小程序」也是有个大概的了解而已。从项目立项到现在大概一个多月,小程序的基本完成了。但还没有上线。不得不说小程序的坑点实在是太多的。这篇系列的文章,主要是对这个项目的复盘和总结。「坑」,踩过一次就好
项目简介
公司在职员工有大几千人,规模不小,但是却是比较传统的企业。公司正在进行数字化转型。之前的售后体系比较复古,主要是通过打电话的方式,然后客服记录客户信息,并在 CSS(售后服务管理系统) 中创建工单,然后分配给师傅。整个流程比较繁琐。而且公司销售渠道也比较多,有线下经销商、线上经销商,还有自己线上自营店铺等待,不同销售渠道,负责售后的主体也不同,这加大了售后的成本和难度。
售后小程序主要就是为了,缩短售后整个流程,减少人工的介入,提高效率,并让售后的数据更规范、系统、可控。
笔友身为一个卑微的前端抠图仔,小程序前端这一块自然就由我这渣渣负责。
小程序功能脑图
share.mubu.com/doc/6SxOx2N…
下面会一个个分析功能点的坑点和实现方式
技术选型
- 开发框架:微信原生框架
- 组件库:vant-weapp 「vant 的微信小程序版」
- 工具库:wxParse「富文本解析」、smartParse 「地址智能识别」、mixin.js「让微信框架也具备像 vue 类似的混入『mixins』功能」
- 第三方服务或插件 :腾讯地图微信小程序SDK以及城市选择器插件、腾讯 TRCT 音视频通话服务
首先公司立项之前没有「跨端、多平台」的需求,只是想做个微信小程序。所以并没有使用 「uni-app」 之类的多平台框架,组件库选择 vant,主要是多人用、社区比较活跃,自己也相对熟悉、UI也长得还不错。
至于工具库、插件和第三方服务,更多的是为了满足功能需要,可选择的也不多。
项目准备前期
大家都知道,项目开发前期,一般都会把每个项目常用的东西准备好,例如,发送请求的 request.js 、时间格式化函数、公共样式等等,我们可以理解为项目模板,又或者是项目的「地基」。例如 vue-cli 生成的项目,只是 vue-cli 的侧重点主要在项目工程化这一块。
做过项目的朋友,手上一般都会有这样的一个模板,每次有新项目的时候,往上面一套。从而达到「提高效率,安心摸鱼专注于业务逻辑」的目的。
之前没怎么做过「微信小程序」的项目,所以自己手头上是没有「模板」,趁这次机会整理个模板。
项目模板: 「wx_template」
封装请求工具类
微信发起请求的方式和原生的 JS 有些区别,微信提供了对应的 API wx.request
,我们要做的就是对 wx.request
进行二次封装。这样可以减少每次请求时,都要传请求头
、超时时间
、Token
等信息。还可以统一管理请求的异常信息,例如:Token过期
、请求失败
等情况,这其实就跟平时常用的二次封装 Axios
一个道理。
request.js实现 主要是参考了
「CRMEB」
公用样式
把一些常用的 CSS 样式提取出来,那个标签需要用到,就加个 class='xxx'
就好。 这样便于复用和维护。
项目里用到了两个文件
app.wxss
普通常用的样式(自定义的组件里面,使用 app.wxss 的样式时,需要先引入@import "app.wxss";
)
variables.wxss
css变量,主要用于覆盖 vant 的默认样式以及一些全局的 CSS 变量
vant默认样式覆盖(px转rpx)
方法一 (使用vant 提供的 css 变量覆盖)
值得一提的是、小弟的项目中,由于用了 vant-weapp
这个组件库,这个组件的 css像素单位
用的是 px
,如果要做移动端自适应。那就需要使用小程序特有的css单位 rpx
。这是不是意味这我要把组件库更 css单位 有关的默认样式都覆盖一遍??纳尼?简直日了个G
。那抓耳挠腮的场景简直了!网上各种搜,乱七八糟答案一大堆。最后还是在文档里看到了希望,可能是太不显眼了,就简单的几行文字描述,之前看文档的时候没有留意。
vant-weapp
覆盖样式的方式有三种,最后选择提供了css 变量
的方式来处理。简单、明了、容维护。
详细查看: youzan.github.io/vant-weapp/…
方法二 (使用 postcss-pxtransform 来转换,推荐使用)
文章 demo 已经实现,详细参考 —— 「vant-weapp 转换像素单位 (px 转 rpx)」
自定义顶部导航栏
小程序导航栏原生提供的配置项比较少,往往不能满足需求,都需要自定义顶部导航栏。项目里面也会有导航栏
的例子,大家可以参考批评一下
自定义导航栏有一个很重要的点就是状态栏的高度(statusBarHeight)
,不同手机这个高度是不一样的。微信提供了一个 API 可获取到这个高度———wx.getSystemInfo
导航栏的高度 = statusBarHeight + height
,这样才能适配不同手机型号
例子:
//app.js
onLaunch() {
wx.getSystemInfo({
success: (res) => {
//获取状态栏高度,并存在 globalData 中
this.globalData.statusBarHeight = res.statusBarHeight
}
})
}
// components/navbar/index.js
lifetimes: {
attached: function () {
this.setData({
//获取在 app.js 的 globalData 中保存的 statusBarHeight
navH: getApp().globalData.statusBarHeight
})
},
},
// 使用css函数 calc() 动态加上状态栏高度
<view class="navbar-fit" style="height: calc(100rpx + {{navH}}px + {{addHeight}}rpx)"></view>
自定义 tabbar
具体怎么实现,可以参考项目模板,就不赘述了。主要说一下「自定义 tabbar」的坑点:
IOS 底部安全距离
自定义 tabbar 会存在 IOS安全距离的问题,安卓底部安全距离会自己加上不用处理。 不知道安全距离朋友,可以参考这篇文章: segmentfault.com/a/119000002…
代码实现:
pages:{
padding-bottom: constant(safe-area-inset-bottom);
/*兼容 IOS<11.2*/
padding-bottom: env(safe-area-inset-bottom);
/*兼容 IOS>11.2*/
}
android 手机页面白屏闪烁问题(未解决)
点击 tabbar 切换页面时,页面会先白屏闪烁,再显示。特别是 「深色导航栏和背景」,闪烁十分明显,虽然不会影响正常功能,但是体验不太好。IOS 和 调试工具都没有出现。这个貌似是微信的bug,我还特意建了测试项目。疯狂尝试网上的各种方法,都不奏效。
最后发现只有一个方法有效,但是其实也是一个取巧
的方法。原理就是在一个页面中实现,多个页面的切换。类似于 Vue 的 SPA(单页应用) 的实现方式。由于对原本项目的改动很大,就没有使用。
实现方法查看: www.yuque.com/colorui/col…
引入「mixin.js」实现类似 Vue 的 mixin(混入)功能
小程序本身是具有 mixin 功能的,可以通过 behaviors
来实现,但是它只能在「组件」中使用,不能实现页面的 mixin 。为了实现页面 mixin ,我们可以引入 「mixin.js」来实现。
先引入mixin.js、再新建一个文件globalMixin.js
,用来统一管理 mixin 的 data、方法等
使用例子:
// globalMixin.js
export const mixin1 = {
data:{
title:"mixin1"
},
getTitle(){
console.log(this.data.title)
}
}
export const mixin2 = {
data:{
title:"mixin2"
},
getTitle(){
console.log(this.data.title)
}
}
//全局页面 mixin
// app.js
import { mixin1 } from "../../commom/globalMixin"
wx.mixin(mixin1)
//局部 mixin
//page1.js
import { mixin2 } from "../../commom/globalMixin"
Page({
mixins: [mixin2],
data: {}
}}
mixins: [mixin2],
具体参考: www.cnblogs.com/chanwahfung…
用 behavior.js 统一管理组件 behavior
小程序组件提供了类似于 Vue
的 mixin(混入)
功能 ——behavior
。behavior.js
用于统一存放 behavior 对象,需要的时候通过 import
按需导入就好
代码实现:
// behavior.js
export const commomProp = Behavior({
data: {
activeColor: "#d70039",
mainColor: "#707070",
}
})
// 自定义组件
import { commomProp } from "../common/behavior"
Component({
behaviors: [commomProp], //使用 behavior
properties: {},
data: {}
})
微信文档: developers.weixin.qq.com/miniprogram…
utils.js 常用工具函数
utils.js
用于存放一些公用的函数,例如格式化日期、压缩图片、防抖、节流等等,把这些方法抽离出来,便于维护和使用。
emun.js 枚举映射
枚举值都可以在这里维护。但并不是最优解,最保险的方式,其实是请求后端的字典接口来获取对应的映射,这样后端改动时,前端就不需要手动维护了。
使用例子:
// emun.js
export const STATUS = {
"1": "待处理",
"2": "处理中",
"3": "已完成",
"4": "已取消",
}
//index.js
//导入枚举对象
import { STATUS } from "../../comom/emun"
const status = 1
this.setData({
status: STATUS[status] //待处理
})
小程序使用 iconfont
iconfont 的引入和我们平时的引入有所不同,小程序 url 是不支持路径的形式的,只能使用 base64 的方式引入字体文件
例子:
// 错误用法
// url 不支持路径
@font-face {
font-family: "iconfont"; /* Project id 2406785 */
src: url('iconfont.woff2?t=1623988771553') format('woff2'),
url('iconfont.woff?t=1623988771553') format('woff'),
url('iconfont.ttf?t=1623988771553') format('truetype');
}
// 正确用法
// 用 tff 文件 转成 base64
@font-face {
font-family: "iconfont"; /* Project id 2406785 */
src: url('data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAA5...),
url('data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAA5...) format('woff'),
url('iconfont.ttf') format('truetype');
}
字体文件转 base64: transfonter.org/
到这里,项目前期的准备工作算完成了。篇幅原因,后面会按 「思维导图」的功能点,一一踩坑。
项目模板地址: 「wx_template」`
相关文章:
微信小程序登录功能的实现以及坑点 —— 前端实现
微信小程序添加地址的三种实现方式 —— 省市区联动选择器、地图选点、智能识别地址