van+mpvue微信小程序入门

3,011 阅读16分钟

1. 介绍

基于van、mpvue开发的微信小程序,记录了开发前的技术选型、开发时如何搭建环境、上手项目、踩坑等。

2. 需求

报销单的填写

2.1. 页面

  • 登录
  • 我的-个人信息
  • 首页

nav导航,填写日志、修改日志,填写报销单、报销单审核,把日志导出发送到指定到邮箱,选择日期查看本人的日志

2.2. 前端技术选型

2.2.1. 框架

image.png
上图图来自掘金的一篇技术选型文章。

我选择的 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 生成的项目如何使用有赞的 van UI组件,并且能正常显示呢?

将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 网络库,它有如下特点:

  1. 提供统一的 Promise API。
  2. 浏览器环境下,轻量且非常轻量
  3. 支持多种JavaScript 运行环境
  4. 支持请求/响应拦截器。
  5. 自动转换 JSON 数据。
  6. 支持切换底层 Http Engine,可轻松适配各种运行环境
  7. 浏览器端支持全局Ajax拦截 。
  8. 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. 服务端框架技术选型

Nodejs

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 配置

注意事项

  1. 新增的页面需要重新 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.push>wx.navigateTo()//进入子页面<br/>    this.router.push-->wx.navigateTo() //进入子页面<br />    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. 循环渲染过多数据出现卡顿

滚动滑动,虚拟dom

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)。

配置流程

服务器域名请在 「小程序后台-开发-开发设置-服务器域名」 中进行配置,配置时需要注意:

2. 网络请求

超时时间

  • 默认超时时间和最大超时时间都是 60s
  • 超时时间可以在 app.jsongame.json 中通过 networktimeout 配置。

使用限制

  • 网络请求的 referer header 不可设置。其格式固定为 https://servicewechat.com/{appid}/{version}/page-frame.html,其中 {appid} 为小程序的 appid,{version} 为小程序的版本号,版本号为 0 表示为开发版、体验版以及审核版本,版本号为 devtools 表示为开发者工具,其余为正式版本;
  • wx.requestwx.uploadFilewx.downloadFile 的最大并发限制是 10 个;
  • wx.connectSockt 的最大并发限制是 5 个。
  • 小程序进入后台运行后,如果 5s 内网络请求没有结束,会回调错误信息 fail interrupted;在回到前台之前,网络请求接口调用都会无法调用。

返回值编码

  • 建议服务器返回值使用 UTF-8 编码。对于非 UTF-8 编码,小程序会尝试进行转换,但是会有转换失败的可能。
  • 小程序会自动对 BOM 头进行过滤(只过滤一个BOM头)。

回调函数

  • 只要成功接收到服务器返回,无论 statusCode 是多少,都会进入 success 回调。请开发者根据业务逻辑对返回值进行判断。

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 是新版本才支持的,那么开发者工具也要更新到最新版本啦,感谢这篇文章解决了我的问题,链接
image.png

iphone8Plus预览模式van组件页面出现空白

**2020-03-13: **调试环境:iPhone8plus,开发者工具V1.02.1911180,在开发者工具中预览、真机调试都能正常显示,但是真机扫描预览模式的二维码,只能看见底部的tabbar,内容区是空白的,如图:image.pngimage.png
解决方案:

  • 使用组件,无法预览?链接

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文件=》重新编译=》在开发者工具中清除缓存=》点击编译=》点击预览=》手机扫码=》正常显示
把这个问题解决了,我的手机预览白屏问题也解决了,开发小程序的时候一定要控制台报错解决了,再去定位一些奇怪的问题。

重启电脑后,启动开发者工具报错

image.png
**解决方案:**关闭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,就可以正常运行了。
image.png

iOS上https网络请求出现request begin,获取不到数据

image.png

image.png

二维数组的对象共享一个内存地址

导致填写报销明细表单时,双向数据绑定的值会影响其他明细表单的值,导致提交失败,通过动态创建内存地址不指向一个地址解决问题。

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等)快速开发?是否支持跨端?等等这些问题都曾困扰着我,但是后来我想的是,勇敢的去做,遇到问题就去解决,总结之后、踩坑多了才会有经验,才能更好帮助自己进行技术选型,越没有经验便会越纠结。