登录后台

页面导航

本文编写于 94 天前,最后修改于 94 天前,其中某些信息可能已经过时。

前言

这段时间给公司开发了一个售后小程序,这也是笔友第一次开发「微信小程序」,之前主要做的是各种管理后台的项目,「微信小程序」也是有个大概的了解而已。从项目立项到现在大概一个多月,小程序的基本完成了。但还没有上线。不得不说小程序的坑点实在是太多的。这篇系列的文章,主要是对这个项目的复盘和总结。「坑」,踩过一次就好

项目简介

公司在职员工有大几千人,规模不小,但是却是比较传统的企业。公司正在进行数字化转型。之前的售后体系比较复古,主要是通过打电话的方式,然后客服记录客户信息,并在 CSS(售后服务管理系统) 中创建工单,然后分配给师傅。整个流程比较繁琐。而且公司销售渠道也比较多,有线下经销商、线上经销商,还有自己线上自营店铺等待,不同销售渠道,负责售后的主体也不同,这加大了售后的成本和难度。

售后小程序主要就是为了,缩短售后整个流程,减少人工的介入,提高效率,并让售后的数据更规范、系统、可控。

笔友身为一个卑微的前端抠图仔,小程序前端这一块自然就由我这渣渣负责。

小程序功能脑图

https://share.mubu.com/doc/6SxOx2NB9x3

下面会一个个分析功能点的坑点和实现方式

技术选型

  • 开发框架:微信原生框架
  • 组件库: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-weapp这个组件库,这个组件的 css像素单位用的是 px,如果要做移动端自适应。那就需要使用小程序特有的css单位 rpx。这是不是意味这我要把组件库更 css单位 有关的默认样式都覆盖一遍??纳尼?简直日了个G 。那抓耳挠腮的场景简直了!网上各种搜,乱七八糟答案一大堆。最后还是在文档里看到了希望,可能是太不显眼了,就简单的几行文字描述,之前看文档的时候没有留意。

1623826152332

vant-weapp覆盖样式的方式有三种,最后选择提供了css 变量的方式来处理。简单、明了、容维护。

详细查看:https://youzan.github.io/vant-weapp/#/custom-style

自定义顶部导航栏

小程序导航栏原生提供的配置项比较少,往往不能满足需求,都需要自定义顶部导航栏。项目里面也会有导航栏的例子,大家可以参考批评一下

自定义导航栏有一个很重要的点就是状态栏的高度(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安全距离的问题,安卓底部安全距离会自己加上不用处理。
不知道安全距离朋友,可以参考这篇文章: https://segmentfault.com/a/1190000020887571

代码实现:

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(单页应用) 的实现方式。由于对原本项目的改动很大,就没有使用。

详细参考:https://www.yuque.com/colorui/colorui/hxp4lh

引入「mixin.js」实现类似 Vue 的 mixin(混入)功能

小程序本身是具有 mixin 功能的,可以通过 behaviors 来实现,但是它只能在「组件」中使用,不能实现页面的 mixin 。为了实现页面 mixin ,我们可以引入 「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],

具体参考:https://www.cnblogs.com/chanwahfung/p/11799365.html

behavior.js 存放组件 behavior

小程序组件提供了类似于 Vuemixin(混入)功能 ——behaviorbehavior.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: {}
})

微信文档:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/behaviors.html

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 : https://transfonter.org/

到这里,项目前期的准备工作算完成了。篇幅原因,后面会按 「思维导图」的功能点,一一踩坑。

项目模板地址:「wx_template」`