微信小程序开发
最后更新于
最后更新于
微信小程序是一种全新的连接用户与服务的方式,它提供了一个简单、高效的应用开发框架和丰富的组件及API,帮助开发者在微信中开发具有原生 APP 体验的服务。
小程序的技术底层依托于 Web 技术,和 Web 端开发相似却又不同。在 Web 中,开发者可以使用浏览器提供的 dom/bom api 来操作渲染内容,同时编写 js 脚本来执行页面逻辑;在小程序中渲染和逻辑则完全分离,开发者可以编写 js 脚本,但是无法直接调用 dom/bom api,渲染和逻辑的交互通过数据和事件来驱动,开发者可以不用再去关心渲染的细节。
小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的 Dom/Bom API。这一区别导致了前端开发非常熟悉的一些库,例如 jQuery、 Zepto 等,在小程序中是无法运行的。同时 JSCore 的环境同 NodeJS 环境也是不尽相同,所以一些 NPM 的包在小程序中也是无法运行的。
Web 开发者需要面对的环境是各式各样的浏览器,PC 端需要面对 IE、Chrome、QQ 浏览器等,在移动端需要面对 Safari、Chrome 以及 iOS、Android 系统中的各式 WebView 。而小程序开发过程中需要面对的是两大操作系统 iOS 和 Android 的微信客户端,以及用于辅助开发的小程序开发者工具,小程序中三大运行环境也是有所区别的:
微信小程序运行在多种平台上: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 分钟)没有使用小程序,或者系统资源紧张,小程序会被「销毁」,即完全终止运行。
基于安全考虑,小程序中不支持动态执行 JS 代码,即:
不支持使用 eval 执行 JS 代码
不支持使用 new Function 创建函数
new Function('return this') 除外
报错: [ 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 中生效。
报错: [ dist/mp/app.json 文件内容错误] dist/mp/app.json: 未找到 ["sitemapLocation"] 对应的 sitemap.json 文件。
解决: 在根目录新建一个 sitemap.json
文件:
或者在 build 后,dist 文件夹中的 sitemap.json
复制到 根目录下。
微信开发者工具: 微信开发者工具顶部工具栏,有【清缓存】功能。
移动端:删除小程序。(如果不启效,尝试把开发版、体验版、线上版都删掉)
重现场景: 在主页跳转到某页面,点击 【添加编译模式】,【自定义编译条件】面板会自动添加如下参数。其中重要的两个参数:启动页面,是 dist/mp/pages
文件夹下的页面路径;启动参数,是 type=jump&targeturl=xxx
。
如图,自动添加的参数是 type=jump&targeturl=https%253A%252F%252Ftest.miniprogram.com%252Firr
,但该页面打开是空白的:
原因: 是微信开发者工具,自动添加的参数 targeturl 有误。将该值解码后,得到的并不是正确的页面路径:
解决方法: 手动 encodeURIComponent
页面路径,配置到面板中【启动参数】属性的 targeturl 参数。
正确配置: 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 进行解析。
参考资料:
wechat-miniprogram / kbone—— Q&A
小程序中不支持 Table 标签。
小程序不支持远程加载 Js、Css;
服务器接口:必须是 https 协议请求,同时请求的域名需要在小程序管理平台进行配置。本地开发时,可在微信开发者工具右上角 详情 -> 本地设置
中,关闭域名校验;
小程序里的所有页面必须同源;
小程序不支持动态追加未声明的属性:如 vue style 的 scoped 属性;
本地资源不能通过 wxss 获取;
background-image: 可以使用网络图片或者 base64
格式;
使用 image 标签。
个人或海外公众号不支持 webview 内嵌h5页面。webview中内嵌的链接来源必须在业务域名内。
wx.navigateTo 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。
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 的跨端库
完整对齐 [wxapis]
同时支持 promise 化和 callback 调用
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 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。
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月)。
表现: vue-router 的 history 模式,在浏览览器中打开,id='app' 节点内没有内容,页面对应的 Js 没有加载。
原因: 未知
解决: 改用 hash 模式。
比如,wx.showToast
是小程序端的 API,web 端无法使用。
解决: 使用 kbone-api。Kbone-API 是一个能同时支持小程序和 Web 端的多端 API 库。
运行环境
逻辑层
渲染层
iOS
JavaScriptCore
WKWebView
安卓
V8
chromium定制内核
小程序开发者工具
NWJS
Chrome WebView