1. 介绍
基于van、mpvue开发的微信小程序,记录了开发前的技术选型、开发时如何搭建环境、上手项目、踩坑等。
2. 需求
报销单的填写
2.1. 页面
- 登录
- 我的-个人信息
- 首页
nav导航,填写日志、修改日志,填写报销单、报销单审核,把日志导出发送到指定到邮箱,选择日期查看本人的日志
2.2. 前端技术选型
2.2.1. 框架
上图图来自掘金的一篇技术选型文章。
我选择的 mpvue ,但是GitHub最新的更新记录是在一年前,团队没有怎么维护了,这个问题也需要注意一下。
官网文档:github.com/Meituan-Dia…mpvue (github 地址请参见)是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。
使用 mpvue 开发小程序,你将在小程序技术体系的基础上获取到这样一些能力:
- 彻底的组件化开发能力:提高代码复用性
- 完整的
Vue.js开发体验 - 方便的
Vuex数据管理方案:方便构建复杂应用 - 快捷的
webpack构建机制:自定义构建策略、开发阶段 hotReload - 支持使用 npm 外部依赖
- 使用
Vue.js命令行工具 vue-cli 快速初始化项目 - H5 代码转换编译成小程序目标代码的能力
2.2.2. UI组件
选择一个合适的 UI 组件,可以帮助我们快速开发项目
GitHub官网: github.com/youzan/vant…
官方文档: youzan.github.io/vant-weapp/…
扫描下方小程序二维码,体验组件库示例:
- 通过
mpvue生成的项目如何使用有赞的vanUI组件,并且能正常显示呢?
将UI组件导入后可在项目册测试,在此之前为了让UI组件生效,我们需要将项目打包一下,即为我们需要打开终端,在项目的根目录下执行一遍(npm run build),这样vant的UI组件就会在页面中正常发挥作用了
2.2.3. 前后端通信
fly: github.com/wendux/fly
一个支持所有JavaScript运行环境的基于Promise的、支持请求转发、强大的http请求库。可以让您在多个端上尽可能大限度的实现代码复用。
目前Fly.js支持的平台包括:Node.js 、微信小程序 、Weex 、React Native 、Quick App 和浏览器,这些平台的 JavaScript 运行时都是不同的。
简介
Fly.js 是一个基于 promise 的,轻量且强大的Javascript http 网络库,它有如下特点:
- 提供统一的 Promise API。
- 浏览器环境下,轻量且非常轻量 。
- 支持多种JavaScript 运行环境
- 支持请求/响应拦截器。
- 自动转换 JSON 数据。
- 支持切换底层 Http Engine,可轻松适配各种运行环境。
- 浏览器端支持全局Ajax拦截 。
- H5页面内嵌到原生 APP 中时,支持将 http 请求转发到 Native。支持直接请求图片。
定位与目标
Fly 的定位是成为 Javascript http请求的终极解决方案。也就是说,在任何能够执行 Javascript 的环境,只要具有访问网络的能力,Fly都能运行在其上,提供统一的API。
官网
详细的文档请移步:Flyio官网文档 。 官网http请求使用的正是fly,为了方便大家验证fly功能特性,官网对fly进行了全局引入,您可以在官网页面打开控制台直接验证。
安装
使用NPM
npm install flyio
使用CDN(浏览器中)
<script src="https://unpkg.com/flyio/dist/fly.min.js"></script>
UMD(浏览器中)
https://unpkg.com/flyio/dist/umd/fly.umd.min.js
2.3. 服务端框架技术选型
3. 快速上手
本文假设你既不会 vue 也不会小程序,如嫌拖沓,请直接快进跳读。
3.1. 初始化一个 mpvue 项目
现代前端开发框架和环境都是需要 Node.js 的,如果没有的话,请先下载 nodejs 并安装。
然后打开命令行工具:
# 1. 先检查下 Node.js 是否安装成功
$ node -v
v8.9.0
$ npm -v
5.6.0
# 2. 由于众所周知的原因,可以考虑切换源为 taobao 源
$ npm set registry https://registry.npm.taobao.org/
# 3. 全局安装 vue-cli
# 一般是要 sudo 权限的
$ npm install --global vue-cli@2.9
# 4. 创建一个基于 mpvue-quickstart 模板的新项目
# 新手一路回车选择默认就可以了
$ vue init mpvue/mpvue-quickstart my-project
# 5. 安装依赖,走你
$ cd my-project
$ npm install
$ npm run dev
随着运行成功的回显之后,可以看到本地多了个 dist 目录,这个目录里就是生成的小程序相关代码。
3.2. 搭建小程序的开发环境
小程序自己有一个专门的微信开发者工具,最新版本下载地址。
这一步比较简单,按照提示一步步安装好就行,然后用微信扫描二维码登陆。 至此小程序的开发环境差不多完成。
3.3. 调试开发 mpvue
选择 小程序项目 并依次填好需要的信息:
- 项目目录:就是刚刚创建的项目目录(非 dist 目录)
- AppID:没有的话可以点选体验“小程序”,只影响是否可以真机调试。
- 项目名称。
如图:
点击“确定”按钮后会跳到正式的开发页面,点击“编辑器”按钮,关闭自带的小程序编辑器。然后如图:
此时,整个 mpvue 项目已经跑起来了。
用自己趁手的编辑器(或者IDE)打开 my-project 中的 src 目录下的代码试试,如示例:
到此,上手完毕。
3.4. 分包机制 2018.7.23+
mpvue-loader 1.1.2-rc.2 之后,优化了 build 后的文件生成结构,生成的目录结构保持了源文件夹下的目录结构,有利于对分包的支持。
3.5. webpack 配置
注意事项
- 新增的页面需要重新
npm run dev来进行编译
温馨提示
在开发小程序之前,第1步、需要准备电脑上的开发环境有 > node 、 > npm 、 > git ,通过 > git 工具创建一个新项目,克隆已有代码。第2步、安装微信开发者工具,比如我们平时是在浏览器控制台上调试代码,微信小程序是通过在开发者工具调试代码的。如果是新项目在开发者工具中点击创建即可,如果是已有项目,点击导入即可。 第3步、第4步、第5步、 第6步、
4. 开发代码
我开发代码是基于 mpvue + van 的,
新增页面需要npm run dev重启一下
记录一些常用的编码、以及注意事项
开源代码参考:
4.1. mpvue
4.1.1. for循环嵌套
<!-- 在这种嵌套循环的时候, index 和 itemIndex 这种索引是必须指定,且别名不能相同,正确的写法如下 -->
<template>
<ul v-for="(card, index) in list">
<li v-for="(item, itemIndex) in card">
{{item.value}}
</li>
</ul>
</template>
4.1.2. 页面跳转
小程序不支持路由,因此,路由跳转使用小程序的页面导航api代替
this.router.replace-->wx.reLaunch()//打开新页面
获取当前页面地址
this.$route.fullPath-->getCurrentPages()[0].route
4.1.3. 表单双向数据绑定与事件绑定
在mpvue中使用如 label="{{name}}"会报错
<van-cell-group>
<van-field
label="用户名"
:value="userInfo.name"
placeholder="请输入用户名"
v-bind:border="false"
@change="onChange($event,'name')"
/>
<van-field
label="密码"
:value="userInfo.password"
placeholder="请输入密码"
v-bind:border="false"
bind:change="onChange($event,'password')"
/>
</van-cell-group>
4.1. mock数据与真实接口如何设计
4.2. api封装
设置首次加载页面
在编译的地方设置,你只需要设置页面的路径,勾选上“使用以上条件编译”,如果页面需要参数,那可以把参数也传上。这样启动的就是你设置的页面。
小程序首次页面加载,可以在app.json中设置,第一个即为首次加载页面
后期考虑加入启动页面(第一次打开小程序会加载)=》登录页面=》首页
4.3. 引入阿里云图标
不引入阿里云图标了,改为使用本地静态图片。
注意事项:记得删除无用文件,否则手机预览时会出现白屏,因为报错啦。
因为小程序没有document,我引入了阿里云图标,里面有document.getElementsByTagName的代码,
到体验版时出现这个问题. 原来是 /static/iconfont/里的 iconfont.js+demo.html....这些无关文件引起的;iconfont文件夹如下即可
4.4. 跳转路由和路由传参数
- 列表页面向详情页面传参数
// 列表页面
/**
* 跳转到报销详情页面
*/
reimbursementDetail(id) {
// 详情页面需在app.json里面引入
let url = `../reimbursementdetail/main?id=${id}`;
wx.navigateTo({url});
}
// 详情页面
mounted() {
this.id = this.$root.$mp.query.id; // 根据id请求详情页面的接口
},
4.5. 自定义nav-bar头部
小程序里面也可以自定义nav-bar,但是没有必要,小程序有自带的头部
4.6. 动态设置title
wx.setNavigationBarTitle({
title: "登录XX管理系统"
});
4.7. 循环渲染过多数据出现卡顿
5. 小程序常见问题
微信开放社区交流: developers.weixin.qq.com/community/d…
5.1. API请求
5.2. 基础库兼容
5.3. 不同页面传值方式
5.4. 跨域问题
控制台,如出现以下提示,是跨域问题
http://www.mxnzp.com 不在以下 request 合法域名列表中,
请参考文档:https://developers.weixin.qq.com/miniprogram/dev/framework/ability/network.html
跳过域名校验
在微信开发者工具中,可以临时开启 开发环境不校验请求域名、TLS版本及HTTPS证书 选项,跳过服务器域名的校验。此时,在微信开发者工具中及手机开启调试模式时,不会进行服务器域名的校验。
在服务器域名配置成功后,建议开发者关闭此选项进行开发,并在各平台下进行测试,以确认服务器域名配置正确。
如果手机上出现 “打开调试模式可以发出请求,关闭调试模式无法发出请求” 的现象,请确认是否跳过了域名校验,并确认服务器域名和证书配置是否正确。
解决办法:developers.weixin.qq.com/miniprogram…
网络
在小程序/小游戏中使用网络相关的 API 时,需要注意下列问题,请开发者提前了解。
1. 服务器域名配置
每个微信小程序需要事先设置通讯域名,小程序只可以跟指定的域名进行网络通信。包括普通 HTTPS 请求(wx.request)、上传文件(wx.uploadFile)、下载文件(wx.downloadFile) 和 WebSocket 通信(wx.connectSocket)。
从基础库 2.4.0 开始,网络接口允许与局域网 IP 通信,但要注意 不允许与本机 IP 通信。
从 2.7.0 开始,提供了 UDP 通信(wx.createUDPSocket)。
配置流程
服务器域名请在 「小程序后台-开发-开发设置-服务器域名」 中进行配置,配置时需要注意:
- 域名只支持
https(wx.request、wx.uploadFile、wx.downloadFile) 和wss(wx.connectSocket) 协议; - 域名不能使用 IP 地址(小程序的局域网 IP 除外)或 localhost;
- 可以配置端口,如 myserver.com:8080,但是配置后只能向 myserver.com:8080 发起请求。如果向 myserver.com、https://myserver.c… 等 URL 请求则会失败。
- 如果不配置端口。如 myserver.com,那么请求的 URL 中也不能包含端口,甚至是默认的 443 端口也不可以。如果向 myserver.com:443 请求则会失败。
- 域名必须经过 ICP 备案;
- 出于安全考虑,
api.weixin.qq.com不能被配置为服务器域名,相关API也不能在小程序内调用。 开发者应将 AppSecret 保存到后台服务器中,通过服务器使用getAccessToken接口获取access_token,并调用相关 API; - 对于每个接口,分别可以配置最多 20 个域名。
2. 网络请求
超时时间
- 默认超时时间和最大超时时间都是 60s;
- 超时时间可以在
app.json或game.json中通过networktimeout配置。
使用限制
- 网络请求的
refererheader 不可设置。其格式固定为https://servicewechat.com/{appid}/{version}/page-frame.html,其中{appid}为小程序的 appid,{version}为小程序的版本号,版本号为0表示为开发版、体验版以及审核版本,版本号为devtools表示为开发者工具,其余为正式版本; - wx.request、wx.uploadFile、wx.downloadFile 的最大并发限制是 10 个;
- wx.connectSockt 的最大并发限制是 5 个。
- 小程序进入后台运行后,如果 5s 内网络请求没有结束,会回调错误信息
fail interrupted;在回到前台之前,网络请求接口调用都会无法调用。
返回值编码
回调函数
3. 常见问题
HTTPS 证书
小程序必须使用 HTTPS/WSS 发起网络请求。请求时系统会对服务器域名使用的 HTTPS 证书进行校验,如果校验失败,则请求不能成功发起。由于系统限制,不同平台对于证书要求的严格程度不同。为了保证小程序的兼容性,建议开发者按照最高标准进行证书配置,并使用相关工具检查现有证书是否符合要求。
对证书要求如下:
- HTTPS 证书必须有效;
- 证书必须被系统信任,即根证书被已系统内置
- 部署 SSL 证书的网站域名必须与证书颁发的域名一致
- 证书必须在有效期内
- 证书的信任链必需完整(需要服务器配置)
iOS不支持自签名证书;iOS下证书必须满足苹果 App Transport Security (ATS) 的要求;- TLS 必须支持 1.2 及以上版本。部分旧
Android机型还未支持 TLS 1.2,请确保 HTTPS 服务器的 TLS 版本支持 1.2 及以下版本; - 部分 CA 可能不被操作系统信任,请开发者在选择证书时注意小程序和各系统的相关通告。
证书有效性可以使用
openssl s_client -connect example.com:443命令验证,也可以使用其他在线工具。
除了网络请求 API 外,小程序中其他 HTTPS 请求如果出现异常,也请按上述流程进行检查。如 https 的图片无法加载、音视频无法播放等。
6. 我的踩坑记录
记录耗费我时间比较久的一些问题,也附上我的踩坑时间,希望能帮助到有需要的人。
小程序坑在哪里?选择第三方框架mpvue,van,那么要注意写法的问题,开发者工具要更新到最新版本,编译时没有出现期望的效果,可能需要清除开发者工具的缓存,或者rm -rf dist,运行npm run dev 命令重新编译,遇到问题先解决控制台的报错,根据提示到微信开发社区 、或者其他搜索引擎去搜索问题,一个一个的解决,不要慌。
usingComponents全局引入van组件不起效果
** 2020-03-02: **使用mpvue搭建的项目,在app.json中,全局引入 van 组件不生效,其实和有赞的组件没有关系,是因为我电脑上的开发者工具很早之前就安装了,而usingComponents 是新版本才支持的,那么开发者工具也要更新到最新版本啦,感谢这篇文章解决了我的问题,链接
iphone8Plus预览模式van组件页面出现空白
**2020-03-13: **调试环境:iPhone8plus,开发者工具V1.02.1911180,在开发者工具中预览、真机调试都能正常显示,但是真机扫描预览模式的二维码,只能看见底部的tabbar,内容区是空白的,如图:
解决方案:
- 使用组件,无法预览?链接
undefined is not an object(evaluating 'document.getElementsByTagName')
解决方案:链接
因为小程序没有document,我引入了阿里云图标,里面有document.getElementsByTagName的代码,
到体验版时出现这个问题. 原来是 /static/iconfont/里的 iconfont.js+demo.html....这些无关文件引起的;iconfont文件夹如下即可
删除无关文件后,需要执行
sudo rm -rf dist
npm run dev
删除整个dist文件=》重新编译=》在开发者工具中清除缓存=》点击编译=》点击预览=》手机扫码=》正常显示
把这个问题解决了,我的手机预览白屏问题也解决了,开发小程序的时候一定要控制台报错解决了,再去定位一些奇怪的问题。
重启电脑后,启动开发者工具报错
**解决方案:**关闭VPN或者抓包工具=》关闭开发者工具=》重启开发者工具=》清除全部缓存=》点击预览=》ok
因为微信开发者工具采用了Https连接,所以任何可能会影响网络的应用程序都应该关闭。
否则可能会对开发者工具造成影响。
does not have a method "onClickLeft" to handle event "click-left".
跳转的页面不可以在app.json中定义,比如说绝对不可以在tabbar的path中定义
解决方案:github.com/youzan/vant…
wx.nextTick is not a function
解决方案:因为设置了基础库,一直没更新基础库,把基础库改成最新的了2.10.2,就可以正常运行了。
iOS上https网络请求出现request begin,获取不到数据
二维数组的对象共享一个内存地址
导致填写报销明细表单时,双向数据绑定的值会影响其他明细表单的值,导致提交失败,通过动态创建内存地址不指向一个地址解决问题。
let parmas = [];
// let obj = {}; 去掉这行代码
console.log(this.formsDetails, "====> this.formsDetails");
for (let i = 0; i < this.formsDetails.length; i++) {
let detail = this.formsDetails[i];
let index = i;
// params.push(obj)去掉这行代码
// 改为动态创建一个对象就不会共享一个内存空间
parmas.push({});
parmas[i]["sno"] = ++index;
parmas[i]["expenseuid"] = this.mainObj.expenseuid;
for (let j = 0; j < detail.length; j++) {
parmas[i][detail[j].field] = detail[j].value;
}
}
console.log(JSON.stringify(parmas, null, 2), "insertPmemExpenseDetail=====>datas");
mpvue嵌套组件数据无法实时更新
解决方案1: 将两个组件合并成一个组件
最简单、最粗糙的方式,将两个组件合并成一个组件,在一个组件内进行数据更新,就不会出现组件之间数据不同步的问题了。
不过这样的的问题就是,当前组件会很大,本来我们就是为了解耦功能,才要拆分组件的,不能再次回到过去吧。
解决方案2: watch
在unit.vue组件中,使用watch监听某个属性的变化,这样外部的数据发生变化时,watch就能监听到:
watch: {
'user.age': function(val, oldVal){
this.render(); // user中的age属性发生变化时,调用render方法
}
}
解决方案3: 采用vuex状态管理数据
多维数组改变长度视图不更新
解决方案:
this.businesstypes = [...this.businesstypes];
7. 构建与发布流程
7.1. 上传代码
在微信开发者工具中上传代码的前提是,该项目导入时,绑定到appid(非测试的appid)与开发者后台到appid一致,上传代码后才能在后台看见提交记录
7.2 开发者后台提交审核
上传代码提交审核申请后,审核时间一般在7个工作日,如现在也想体验线上版本,那么我们可以在后台设置一个线上体验版本,并且设置体验成员(没有设置为体验成员扫码二维码是无法打开小程序的),这样内部的开发人员、测试等成员可以提前体验线上版本。
8. 用户体验
8.1. 不自定义nav-bar
- 不自定义
微信本身有自带的nav-bar,也支持返回上一个页面,我没有选择自定义nav-bar,而是选择微信自带的导航栏和动态设置title。
**我的出发点:**小程序,越轻量级越好,不追求花枝招展,在于功能的易用性、流畅性、便捷性、即用即走。
8.2. 提交按钮固定在底部
**我的出发点:**用户在填写表单过程中,不用再次滚动也能操作提交按钮,按钮明显、易用。
8.2. 登录按钮禁用
如果用户名或者密码为空,直接禁用按钮,而不是通过文字提示用户用户名或者密码不能为空
参考资料
结语
记录这篇文章,更重要的是去记录一个解决问题的过程,做一个好的小程序还有很多更好的方案,我也需要慢慢的摸索。
其实我在技术选型的问题上也面临了纠结,到底是选择用微信小程序原生开发灵活性比较强呢?还是去选择一个小程序框架(比如mpvue、taro等)快速开发?是否支持跨端?等等这些问题都曾困扰着我,但是后来我想的是,勇敢的去做,遇到问题就去解决,总结之后、踩坑多了才会有经验,才能更好帮助自己进行技术选型,越没有经验便会越纠结。