一份热乎的2022年微信小程序使用经验

7,094 阅读12分钟

上个月写了一个公司的微信小程序项目,趁热打铁,分享一篇开发教程,希望对还没有小程序开发经验的同学有点帮助,对于有 VUE 经验的同学来说,看完这一篇就可以直接上手。

这篇文章我们用提问的方式来完成,带着问题来学习更轻松哟!

搜索 tips 可以直接查看避坑经验。

小程序的框架原理?

视图层加逻辑层,视图层负责渲染,逻辑层负责处理事件。渲染层和逻辑层处于两个线程,通过 微信客户端 通讯。

小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。整个小程序框架系统分为两部分:
逻辑层(App Service)和 视图层(View)。
小程序提供了自己的视图层描述语言 WXML 和 WXSS,以及基于 JavaScript 的逻辑层框架,并在 视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。

为什么微信小程序中不能使用 alert?

因为小程序中没有 window 和 document 对象

小程序框架的逻辑层并非运行在浏览器中,因此 JavaScript 在 web 中一些能力都无法使用,如 window,document 等。

为什么小程序中不能使用 div?

因为小程序的 WXML 并不是原生的 HTML,而是微信自己实现的基于 XML 的语法。在开发过程中使用微信小程序的标签语言规范。 举个例子:

  • view 标签代替 div
  • image 标签代替 img

小程序 js 运行环境和浏览器 js 运行环境有什么不同?

小程序中开发者工具的 js 运行在 nw.js 中,浏览器中的 js 运行在浏览器的 V8 引擎中。

微信小程序运行在多种平台上:iOS/iPadOS 微信客户端、Android 微信客户端、Windows PC 微信客户端、Mac 微信客户端、小程序硬件框架和用于调试的微信开发者工具等。不同运行环境下,脚本执行环境以及用于组件渲染的环境是不同的,性能表现也存在差异:
在 iOS、iPadOS 和 Mac OS 上,小程序逻辑层的 JavaScript 代码运行在 JavaScriptCore 中,视图层是由 WKWebView 来渲染的,环境有 iOS 14、iPad OS 14、Mac OS 11.4 等;
在 Android 上,小程序逻辑层的 JavaScript 代码运行在 V8 中,视图层是由基于 Mobile Chromium 内核的微信自研 XWeb 引擎来渲染的;
在 Windows 上,小程序逻辑层 JavaScript 和视图层都是用 Chromium 内核;
在 开发工具上,小程序逻辑层的 JavaScript 代码是运行在 NW.js 中,视图层是由 Chromium Webview 来渲染的。

运行环境逻辑层渲染层
iOSJavaScriptCoreWKWebView
安卓V8chromium 定制内核
小程序开发者工具NWJSChrome WebView

小程序开发的前置工作?

  1. 使用一个还未注册过公众号或者小程序的邮箱注册一个小程序账号
  2. 添加开发者:小程序管理后台-管理-成员管理-项目成员
  3. 开发者下载最新版的微信开发者工具,选择一个模板(支持 typescript)填入 APPID 生成项目
  4. 熟悉微信开发者工具界面功能

tips:微信开发者工具界面的内容比较多,可以将模拟器界面分离出来,在两个界面展示

小程序的相关文件类型?

类型描述
.WXML标签语言,结合基础组件、事件系统,可以构建出页面的结构
.WXSS样式语言,用于描述 WXML 的组件样式
.json页面配置,例如:导航栏标题、是否支持下拉刷新等
.jsjs 逻辑,事件交互逻辑、http 请求等

tips:iOS 设备对于 input 标签的 maxlength 属性支持不流畅,当输入法为中文时,会将拼音也计算为 value 长度,替代方案为在 bindinput 方法中监听长度变化

如何新增一个页面?

在小程序开发者工具上,找到项目的根目录下的app.json,配置page字段

  {
      "pages":[
        "pages/test/index",
      ]
  }

保存之后会自动在pages目录下生成一个test文件夹,文件夹内包含一个页面需要的四个文件。
tips:

  1. 只有在微信开发者工具上才能触发自动创建文件,在VScode中不能触发
  2. 如果使用VScode开发小程序,需要安装 "小程序开发助手" 插件

如何设置底部 tab 栏?

在 app.json 中配置 tabBar 字段

  "tabBar": {
  "color": "#bfbfbf",
  "selectedColor": "#2056F0",
  "list": [
    {
      "pagePath": "pages/home/index",
      "text": "首 页",
      "iconPath": "/images/home.png",
      "selectedIconPath": "/images/home2.png"
    },
    {
      "pagePath": "pages/customer/index",
      "text": "客 户",
      "iconPath": "/images/customer.png",
      "selectedIconPath": "/images/customer2.png"
    },
    {
      "pagePath": "pages/setting/index",
      "text": "设 置",
      "iconPath": "/images/mine.png",
      "selectedIconPath": "/images/mine2.png"
    }
  ]
}

其他页面配置也可在 app.json 中配置 页面配置

如何设置统一背景色?

在 app.wxss 中设置:

page {
  background-color: #f5f7fa;
}

css 单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为 750rpx。如在 iPhone6 上,屏幕宽度为 375px,共有 750 个物理像素,则 750rpx = 375px = 750 物理像素,1rpx = 0.5px = 1 物理像素。

tips:ios 设备上不支持 gap 属性

小程序的生命周期函数?

函数描述
onLoad页面加载完毕时执行,初始化数据放在这里
onReady页面初次渲染完成时执行
onShow页面显示时执行,再次进入页面时触发的逻辑放在这里
onHide页面隐藏时执行

小程序的双向绑定和 vue 有什么不同?

vue 中的双向绑定数据变动时自动触发视图更新,在小程序中需要调用 this.setData 方法出发视图更新

小程序中的消息提示框

wx.showToast({
  title: "请求成功",
  icon: "success",
  duration: 1500,
});

tips: 在实际使用的过程中,会发现这个消息提示框不能按照设置的持续时间执行,我们可以手动 hide 消息提示框:

setTimeout(function () {
  wx.hideToast();
  wx.navigateBack({
    delta: 1,
  });
}, 1000);

消息提示框

小程序中的模态对话框

wx.showModal({
  title: "提示",
  content: "这是一个模态弹窗",
  success(res) {
    if (res.confirm) {
      console.log("用户点击确定");
    } else if (res.cancel) {
      console.log("用户点击取消");
    }
  },
});

模态对话框

小程序如何更新页面?

调用 setData 方法实现局部数据刷新

页面间传递数据的方式?

  1. 在页面跳转的 URL 后面添加参数,实现页面间传参
// a页面
  wx.navigateTo({
    url: '../customerDetail/index?customerId='+ id,
    success: function(res) {}
  })
  // b页面
  onLoad: function (options) {
    const customerId = options.customerId
  }
  1. 借助 app.globalData,实现一处更改全局更新
// a页面
app.globalData.userInfo = { name: "testName", age: 18 };
// b页面
const app = getApp();
const name = app.globalData.userInfo.name;
  1. 使用 storage

如何实现数据绑定?

// WXML
<view> {{ message }} </view>;
// js
Page({
  data: {
    message: "Hello MINA!",
  },
});

数据绑定

如何实现事件绑定?

bindtap、catchtap 等

事件分为冒泡事件和非冒泡事件:
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。

// WXML
<view bindtap="viewTap"> click me </view>;
// js
Page({
  viewTap: function () {
    console.log("view tap");
  },
});

事件绑定

如何向事件中传递参数?

事件对象可以携带额外信息,如 id, dataset, touches。

// WXML
<view wx:for="list" data-name="{{item.name}}" bindtap="ontap"></view>
// js
ontap:function(e){
  const itemName = e.currentTarget.dataset.name
}

bindtap 和 catchtap 的区别?

  1. bindtap 绑定事件,允许事件冒泡
  2. catchtap 绑定事件,并阻止事件冒泡
    当子节点和父节点都有点击事件时,子节点使用 catchtap,父节点使用 bindtap

页面跳转的方式有哪些?

路由方法描述
wx.navigateTo保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。最多 10 层页面栈
wx.redirectTo关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面
wx.switchTab跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
wx.navigateBack关闭当前页面,返回上一页面或多级页面
wx.reLaunch关闭所有页面,打开到应用内的某个页面

条件渲染怎么做?

  <view wx:if="{{condition}}">按条件展示</view>

tips:频繁渲染用 hidden 代替,类似于 VUE 中 v-if 和 v-show 的区别 条件渲染

循环渲染怎么做?

  <view wx:for="{{list}}" wx:key="id" wx:for-item="user">
    {{user.name}}
  </view>

列表渲染

如何请求数据?

在小程序管理后台-开发-开发管理-开发设置-服务器域名-request 合法域名 中配置服务端域名

wx.request({
  url: "https://www.test.com/api/userList",
  header: {},
  data: {
    pageIndex: 1,
    pageSize: 10,
  },
  timeout: 20000,
  success: function (res) {
    // 成功回调
  },
  fail: function (e) {
    // 失败回调
  },
});

tips:

  1. GET 请求传递数组会被编码,所以传递数组参数时需要使用使用 post 请求
  2. header 中的字段值不支持中文 必须编码后传输,可以使用 encodeURIComponent 方法
  3. 支持 promise 封装

wx.request

上传图片怎么做?

  1. 在小程序管理后台-开发-开发管理-开发设置-服务器域名-uploadFile 合法域名中配置服务器域名
  2. 使用 wx.uploadFile,一般配合 wx.chooseImage 等方法使用:
wx.uploadFile({
  url: "url",
  filePath: "filePaths",
  name: "file",
  formData: {
    user: "test",
  },
  success: function (res) {},
  fail: function (e) {},
  complete: function (res) {},
});

tips: 注意后端支持的最大图片 size,不同手机拍照的图片大小差异很大,andriod 大概 6M,IOS 大概 10M

wx.uploadFile wx.chooseImage

播放录音怎么做?

const audioContext = wx.createInnerAudioContext({
  useWebAudioImplement: true,
});
audioContext.src = "audioUrl";
audioContext.play(); // 播放

wx.createInnerAudioContext

如何实现下拉刷新?

在 json 文件中设置允许下拉刷新:

"enablePullDownRefresh": true,

在 js 文件中添加下拉刷新的回调:

onPullDownRefresh: function () {
  // 下拉回调
  // ...
  // 回调完成之后停止下拉刷新
  wx.stopPullDownRefresh();
},

一般用于下拉刷新页面请求。

如何实现触底更新?

在 js 页面中添加 onReachBottom 的回调:

onReachBottom: function () {
  // 触底回调
}

一般用于列表数据太多时,分页加载。

如何引入 moment 等 npm 包?

  1. 在小程序的根目录下执行:
  npm i moment -S
  1. 在微信开发者工具界面找到-工具-构建 npm

如何使用开发者工具开发企业微信小程序?

  1. 微信开发者工具-工具-插件-添加企业微信小程序插件
  2. 选择当前使用的企业

tips:

  1. 开发人员从企业微信中打开小程序看到的总是开发版
  2. 给测试人员添加体验版权限而不是开发者,原因同上
  3. 企业微信获取到的通讯录个人信息中不包含员工的姓名和手机号,只有 id 和别名等信息

小程序何时销毁?

如果用户很久没有使用小程序,或者系统资源紧张,小程序会被「销毁」,即完全终止运行。具体而言包括以下几种情形:
当小程序进入后台并被「挂起」后,如果很长时间(目前是 30 分钟)都未再次进入前台,小程序会被销毁。
当小程序占用系统资源过高,可能会被系统销毁或被微信客户端主动回收。
在 iOS 上,当微信客户端在一定时间间隔内连续收到系统内存告警时,会根据一定的策略,主动销毁小程序,并提示用户 「运行内存不足,请重新打开该小程序」。具体策略会持续进行调整优化。
建议小程序在必要时使用 wx.onMemoryWarning 监听内存告警事件,进行必要的内存清理。
基础库 1.1.0 及以上,1.4.0 以下版本: 当用户从扫一扫、转发等入口(场景值为 1007, 1008, 1011, 1025)进入小程序,且没有置顶小程序的情况下退出,小程序会被销毁。

tips: 小程序打开后,在短期内再次进入小程序不会从头开始执行,而会直接吊起内存中的页面到前台运行。

tips: 借助 wx.getUpdateManager 实现版本更新

小程序的环境控制?

  • 开发版 扫描开发者工具上的预览二维码生成开发版
    在小程序管理后台的-管理-成员管理-项目成员中添加开发者
    在小程序管理后台的-管理-版本管理-开发版本中查看体验版二维码

  • 体验版
    在开发者工具上点击上传后的代码生成体验版
    在小程序管理后台的-管理-成员管理-项目成员中添加体验成员

  • 审核版
    在小程序管理后台的-管理-版本管理-审核版本中查看审核详情

  • 正式版
    在小程序管理后台的-管理-版本管理-线上版本中查看线上版本详情

    tips:

    1. 设置体验版时,需要注意设置页面路径,可以只提供体验单个页面
    2. 提交审核时,同时提交图片和操作视频,更容易通过审核
    3. 提交审核的版本,必须满足没有任何权限也能正常进入页面(可提供游客身份),否则无法审核通过
    4. 生成的开发版预览码 30 分钟内过期,体验码长期有效

小程序的发布流程?

在微信开发者工具中点击上传代码
在小程序管理后台的-管理-版本管理-开发版本中查看当前版本并提交审核
在小程序管理后台的-管理-版本管理-审核版本中查看审核详情

tips: 小程序发布支持灰度发布,可以指定微信号发布,非常 nice!

写在最后

如果是新的微信小程序项目,建议直接使用微信小程序原生方式开发,看了很多吐槽原生不好用的文章,发现截止 2022 年的现在,微信官方已经修复和优化了大部分的功能,特别是非常重要的功能,原生开发已经没有太大的阻碍。 关注小姐姐,一起学一学!

奇妙的知识

前端请装上这个chrome插件
前端妹子应该掌握的javascript基础
前端妹子应该掌握的git基础