微信小程序开发

微信小程序是一种全新的连接用户与服务的方式,它提供了一个简单、高效的应用开发框架和丰富的组件及API,帮助开发者在微信中开发具有原生 APP 体验的服务。

小程序的技术底层依托于 Web 技术,和 Web 端开发相似却又不同。在 Web 中,开发者可以使用浏览器提供的 dom/bom api 来操作渲染内容,同时编写 js 脚本来执行页面逻辑;在小程序中渲染和逻辑则完全分离,开发者可以编写 js 脚本,但是无法直接调用 dom/bom api,渲染和逻辑的交互通过数据和事件来驱动,开发者可以不用再去关心渲染的细节。

小程序与普通web开发的区别

小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的 Dom/Bom API。这一区别导致了前端开发非常熟悉的一些库,例如 jQuery、 Zepto 等,在小程序中是无法运行的。同时 JSCore 的环境同 NodeJS 环境也是不尽相同,所以一些 NPM 的包在小程序中也是无法运行的。

Web 开发者需要面对的环境是各式各样的浏览器,PC 端需要面对 IE、Chrome、QQ 浏览器等,在移动端需要面对 Safari、Chrome 以及 iOS、Android 系统中的各式 WebView 。而小程序开发过程中需要面对的是两大操作系统 iOS 和 Android 的微信客户端,以及用于辅助开发的小程序开发者工具,小程序中三大运行环境也是有所区别的:

运行环境 逻辑层 渲染层
iOS JavaScriptCore WKWebView
安卓 V8 chromium定制内核
小程序开发者工具 NWJS Chrome WebView

小程序的运行环境

微信小程序运行在多种平台上: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 Chrome 内核的自研 XWeb 引擎来渲染的;
  • 在 Windows 上,小程序逻辑层 javascript 和视图层 javascript 都是用 Chrome 内核;
  • 在 开发工具上,小程序逻辑层的 javascript 代码是运行在 NW.js 中,视图层是由 Chromium Webview 来渲染的。

尽管各运行环境是十分相似的,但是还是有些许区别:

  • JavaScript 语法和 API 支持不一致:语法上开发者可以通过开启 ES6 转 ES5 的功能来规避(详情);此外,小程序基础库内置了必要的 Polyfill,来弥补 API 的差异(详情)。

  • WXSS 渲染表现不一致:尽管可以通过开启样式补全来规避大部分的问题,还是建议开发者需要在 iOS 和 Android 上分别检查小程序的真实表现。

开发者工具仅供调试使用,最终的表现以客户端为准。

小程序运行机制

小程序启动会有两种情况,一种是「冷启动」,一种是「热启动」。

  • 热启动:用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台状态的小程序切换到前台。

    如果每次打开页面都需要刷新数据,可以在生命周期 onShow 中加刷新逻辑。

  • 冷启动:用户首次打开或小程序被微信主动销毁后再次打开的情况,需要重新加载页面资源。

如果用户很久(目前是 30 分钟)没有使用小程序,或者系统资源紧张,小程序会被「销毁」,即完全终止运行。

JavaScript 支持情况

基于安全考虑,小程序中不支持动态执行 JS 代码,即:

  • 不支持使用 eval 执行 JS 代码
  • 不支持使用 new Function 创建函数
  • new Function('return this') 除外

小程序常见问题

app.json 未找到?

报错: [ app.json 文件内容错误] app.json: app.json 未找到,未找到入口 app.json 文件,或者文件读取失败,请检查后重新编译。

原因: 由于 project.config.json 文件的 miniprogramRoot 属性找不到 app.json的路径。

  • 场景一: 项目没有 app.json 文件。

    原因是你没有打包项目,也就是,没有运行 npm run dev 或者 npm run build 生成小程序的运行文件。小程序打包的文件一般在 dist 目录(具体取决于你项目的编译结果) 。

  • 场景二: 不存在 project.config.json 文件。

    小程序运行会先读取根目录下的 project.config.json 配置文件。如果项目根目录下找不到这个文件,可能是你没有打包项目,或者打包生成的 dist 目录的 project.config.json 文件没有自动复制到根目录下(可以手动复制下)。

  • 场景三:project.config.json 文件没有 miniprogramRoot 属性,或者 miniprogramRoot 指定的路径是错误的。

    miniprogramRoot 指定小程序运行的根目录,即 app.json 所在的目录。一般是 ./dist/./dist/mp/,具体取决于你项目的编译结果。

参考资料: 解决微信小程序报[ app.json 文件内容错误] app.json: app.json 未找到,未找到入口 app.json 文件,或者文件读取失败,请检查后重新编译。小程序app.json报错

开发者工具打开空白?

项目启动后,微信开发者工具打开页面是空白的,其原因可能是项目指定的小程序源码的目录不对。

以 taro 框架为例:

默认情况下,微信开发者工具以 project.config.json 文件的 miniprogramRoot 配置(默认:"dist/")为小程序源码目录。由于 taro 是支持多端开发的,微信小程序的源码是输出到 dist/weapp,所以微信开发者工具读取的目录是错误的。

解决方法有两种:

  • 修改 project.config.json 或者 project.private.config.json 文件的 miniprogramRoot 配置为 dist/weapp。
  • 微信开发者工具导入小程序项目时,指定为项目下的 dist/weapp 目录。

project.private.config.json 中的相同设置优先级高于 project.config.json。

开发者工具内的设置修改会优先覆盖 project.private.config.json 的内容。如在 project.private.config.json 有 appid 字段,那么在 详情-基本信息 中修改了 appid,则会优先使用开发者工具配置的 appid。

开发阶段相关的设置修改优先同步到 project.private.config.json 中,与最终编译产物有关的设置无法在 project.private.config.json 中生效。

sitemap.json 未找到?

报错: [ dist/mp/app.json 文件内容错误] dist/mp/app.json: 未找到 ["sitemapLocation"] 对应的 sitemap.json 文件。

解决: 在根目录新建一个 sitemap.json 文件:

{
  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
  "rules": [{
    "action": "allow",
    "page": "*"
  }]
}

或者在 build 后,dist 文件夹中的 sitemap.json 复制到 根目录下。

怎么清除小程序缓存?

  • 微信开发者工具: 微信开发者工具顶部工具栏,有【清缓存】功能。
  • 移动端:删除小程序。(如果不启效,尝试把开发版、体验版、线上版都删掉)

微信开发者工具,自定义路径无法打开?

重现场景: 在主页跳转到某页面,点击 【添加编译模式】,【自定义编译条件】面板会自动添加如下参数。其中重要的两个参数:启动页面,是 dist/mp/pages 文件夹下的页面路径;启动参数,是 type=jump&targeturl=xxx

image-20211116093641336

如图,自动添加的参数是 type=jump&targeturl=https%253A%252F%252Ftest.miniprogram.com%252Firr,但该页面打开是空白的:

image-20211116095124024

原因: 是微信开发者工具,自动添加的参数 targeturl 有误。将该值解码后,得到的并不是正确的页面路径:

decodeURIComponent('https%253A%252F%252Ftest.miniprogram.com%252Firr')
// https%3A%2F%2Ftest.miniprogram.com%2Firr

解决方法: 手动 encodeURIComponent 页面路径,配置到面板中【启动参数】属性的 targeturl 参数。

encodeURIComponent('https://test.miniprogram.com/irr')
// https%3A%2F%2Ftest.miniprogram.com%2Firr

正确配置: type=jump&targeturl=https%253A%252F%252Ftest.miniprogram.com%252Firr

扩展:

Q:已知 location.href,如何封装成对应的小程序的页面路由?

A:先找到对应的页面路径,假设是 pages/home/index,那么封装方式:/pages/home/index?type=${type}&targeturl=${encodeURIComponent(location.href)}&search=${encodeURIComponent(location.search)}&hash=${encodeURIComponent(location.hash)}。type 支持 open(新开页面)、jump(页面内跳转)和 share(分享进入),一般在配置体验版、添加工具模式等情况下使用 type=open 即可;targeturl 是经过编码的 location.href(也可以是 /test/abcde?id=123#hash 这样不带 origin 的 url,以缩减页面路由的长度,kbone 会自动取配置中的 origin 进行拼接);search 和 hash 可传可不传,如若不传,则取 targeturl 中的 search 和 hash 进行解析。

参考资料:

小程序自定义路径无法打开。 #252

wechat-miniprogram / kbone—— Q&A

其他

  • 小程序中不支持 Table 标签。

  • 小程序不支持远程加载 Js、Css;

  • 服务器接口:必须是 https 协议请求,同时请求的域名需要在小程序管理平台进行配置。本地开发时,可在微信开发者工具右上角 详情 -> 本地设置 中,关闭域名校验;

  • 小程序里的所有页面必须同源;

  • 小程序不支持动态追加未声明的属性:如 vue style 的 scoped 属性;

  • 本地资源不能通过 wxss 获取;

    • background-image: 可以使用网络图片或者 base64 格式;
    background-image: url(https://www.test.com/images/test.jpg);
    background-image: url(data:image/png;base64,...);
    
    • 使用 image 标签。
    <image src="/images/test.png"></image>
    
  • 个人或海外公众号不支持 webview 内嵌h5页面。webview中内嵌的链接来源必须在业务域名内。

  • wx.navigateTo 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。

开发框架

kbone

kbone 是一个致力于微信小程序和 Web 端同构的解决方案。

微信小程序的底层模型和 Web 端不同,我们想直接把 Web 端的代码挪到小程序环境内执行是不可能的。kbone 的诞生就是为了解决这个问题,它实现了一个适配器,在适配层里模拟出了浏览器环境,让 Web 端的代码可以不做什么改动便可运行在小程序里。

它有以下特性:

  • 大部分流行的前端框架都能够在 kbone 上运行,比如 Vue、React、Preact 等。

  • 支持更为完整的前端框架特性,因为 kbone 不会对框架底层进行删改(比如 Vue 中的 v-html 指令、Vue-router 插件)。

  • 提供了常用的 dom/bom API,让用户代码无需做太大改动便可从 Web 端迁移到小程序端。以于一些无法完美兼容到小程序端的 API 也提供了一些 dom/bom 扩展 API,比如:getComputedStyle、$$getBoundingClientRect 接口。

  • 可使用 kbone-ui。kbone-ui 是一个支持在 Web 端使用小程序内置组件和 weui 组件的 UI 库。

    kbone 在小程序端支持了内置组件和 weui 组件库的使用,但是这些是小程序端的特性,在 Web 端不可使用。kbone 提供了 kbone-ui 来磨平大部分的组件实现差异,方便跨端同构

    kbone-ui 目前有两个实现版本,版本间无法兼容:

    • 1.x 版本:基于 Web Components 实现,无框架依赖,支持更完整的组件列表
    • 0.x 版本:基于 vue 实现,可通过 npm install kbone-ui@core-v0 安装。
  • 可使用 kbone-api。Kbone-API 是一个能同时支持小程序和 Web 端的多端 API 库。它有以下特征:

    • 针对基于 Kbone 的多端开发,满足在 Web 上直接使用小程序相关 API
    • 不依赖 Kbone 和 Kbone-UI,一个无依赖的小程序 API 的跨端库
    • 完整对齐 wx[apis]
    • 同时支持 promise 化和 callback 调用

Taro

Taro 是一个开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发 微信 / 京东 / 百度 / 支付宝 / 字节跳动 / QQ / 飞书 小程序 / H5 / RN 等应用。

它有如下特性:

  • 多端转换支持: Taro 3 可以支持转换到 H5、ReactNative 以及任意小程序平台。
  • 框架支持: 在 Taro 3 中可以使用完整的 React / Vue / Vue3 / Nerv 开发体验。
  • Taro UI: 一款基于 Taro 框架开发的多端 UI 组件库。Taro UI 特性:
    • 基于 Taro 开发 UI 组件;
    • 一套组件可以在多端适配运行(ReactNative 端暂不支持);
    • 提供友好的 API,可灵活的使用组件。

uni-app

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

mpvue

mpvue 是一个使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。

mpvue 作为小程序版本的 Vue.js,在框架 SDK 之外,完整的技术体系还包括如下设施:

  • mpvue-loader: 提供 webpack 版本的加载器
  • mpvue-webpack-target: webpack 构建目标
  • postcss-mpvue-wxss: 样式代码转换预处理工具
  • px2rpx-loader: 样式转化插件
  • mpvue-lint: 开发辅助插件,包括语法检查,内存检查等功能

注意: mpvue 已长时间未更新了,最近一次更新是2年前(当前 2021年11月)。

kbone常见问题

web 端,vue-router 单页面打开空白?

表现: vue-router 的 history 模式,在浏览览器中打开,id='app' 节点内没有内容,页面对应的 Js 没有加载。

原因: 未知

解决: 改用 hash 模式。

web 端怎么使用小程序 API?

比如,wx.showToast 是小程序端的 API,web 端无法使用。

解决: 使用 kbone-api。Kbone-API 是一个能同时支持小程序和 Web 端的多端 API 库。

import kboneAPI from 'kbone-api'
kboneAPI.showToast({ title: 'use kbone-api' })

// 或者
Vue.use(kboneAPI)
this.$api.showToast({ title: 'use kbone-api' })

小程序端如何获取元素宽高?

Dom.$$getBoundingClientRect().then((res) => {
  console.log(res.width)
  console.log(res.height)
})
© lizhao all right reserved,powered by Gitbook文件修订时间: 2022-05-11 19:10:07

results matching ""

    No results matching ""