微信小程序开发笔记
小程序发展史
小程序并非凭空冒出来的一个概念。当微信中的 WebView 逐渐成为移动 Web 的一个重要入口时,微信就有相关的 JS API 了。实际上,微信官方是没有对外暴露过如此调用的,此类 API 最初是提供给腾讯内部一些业务使用,很多外部开发者发现了之后,依葫芦画瓢地使用了,逐渐成为微信中网页的事实标准。2015年初,微信发布了一整套网页开发工具包,称之为 JS-SDK,开放了拍摄、录音、语音识别、二维码、地图、支付、分享、卡券等几十个API。给所有的 Web 开发者打开了一扇全新的窗户,让所有开发者都可以使用到微信的原生能力,去完成一些之前做不到或者难以做到的事情。
小程序与普通网页开发的区别
小程序的主要开发语言是 JavaScript ,小程序的开发同普通的网页开发相比有很大的相似性。对于前端开发者而言,从网页开发迁移到小程序的开发成本并不高,但是二者还是有些许区别的。
网页开发渲染线程和脚本线程是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应,而在小程序中,二者是分开的,分别运行在不同的线程中。网页开发者可以使用到各种浏览器暴露出来的 DOM API,进行 DOM 选中和操作。而如上文所述,小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的DOM API和BOM API。这一区别导致了前端开发非常熟悉的一些库,例如 jQuery、 Zepto 等,在小程序中是无法运行的。同时 JSCore 的环境同 NodeJS 环境也是不尽相同,所以一些 NPM 的包在小程序中也是无法运行的。
网页开发者需要面对的环境是各式各样的浏览器,PC 端需要面对 IE、Chrome、QQ浏览器等,在移动端需要面对Safari、Chrome以及 iOS、Android 系统中的各式 WebView 。而小程序开发过程中需要面对的是两大操作系统 iOS 和 Android 的微信客户端,以及用于辅助开发的小程序开发者工具,小程序中三大运行环境也是有所区别的,如表1-1所示。
表1-1 小程序的运行环境
运行环境 | 逻辑层 | 渲染层 |
---|---|---|
iOS | JavaScriptCore | WKWebView |
安卓 | V8 | chromium定制内核 |
小程序开发者工具 | NWJS | Chrome WebView |
微信小程序的开通注册流程
* 途径一
通过网站注册登陆–: (微信公众平台): https://mp.weixin.qq.com/ --: (登陆) 选择主体类型 – : 开通
具体流程 (因为我已经开通过了,所以无法再次回到那个页面,用的官方的图)— :
进入小程序注册页 根据指引填写信息和提交相应的资料,就可以拥有自己的小程序帐号。
在这个小程序管理平台,你可以管理你的小程序的权限,查看数据报表,发布小程序等操作。
登录 小程序后台 ,我们可以在菜单 “开发”-“开发设置” 看到小程序的 AppID 了 。
小程序的 AppID 相当于小程序平台的一个身份证,后续你会在很多地方要用到 AppID (注意这里要区别于服务号或订阅号的 AppID)。
有了小程序帐号之后,我们需要一个工具来开发小程序。
安装开发工具
前往 开发者工具下载页面 ,根据自己的操作系统下载对应的安装包进行安装,有关开发者工具更详细的介绍可以查看 《开发者工具介绍》 。
* 途径二
就是反着来,你直接在开发者工具生成了测试号,然后去登陆就行勒,一般为了方便,都是采用途径一
通过开发者工具上传,下次登陆微信公众平台的时候选择自己的测试号,需要注意的是个人主体 公众号 小程序号只能有一个,所以如果自己一开始开通了公众号将无法发布小程序,进入的界面也会不一样
安装微信小程序开发者工具
一般选用的是稳定版本,下载安装过程此处不再介绍,推荐别安装C盘;
界面
启动页
登录页
在登录页,可以使用微信扫码登录开发者工具,开发者工具将使用这个微信帐号的信息进行小程序的开发和调试。
具体工具使用此处不在讨论重点,所以此处略过;
进入正题之前的叨叨, 工程项目 && 模块化
对于工程项目: 一个工程项目,不只是模块化,还有项目的跟进更新,从代码规范,到项目整体设计,如何让项目越写越好写,而不是要么在埋坑,要么在堆垃圾代码,所以对项目的整体架构是十分重要的,不仅仅是后端,前端也一样,都会去考虑到项目本身之外的东西,而不是只专注于一个页面,或者功能点,做积木的人和堆积木的人之间的区别,或许就是为什么后者被人们称之为工程师的原因吧,因此对项目有一个整体的宏观考虑之后,再去做局部优化,也就是要有一个项目宏观的概念,由表及里,而模块化,也就是分开做积木,积木的稳健也会影响到整个成品的稳定程度,所以局部优化必不可少,但是如果能支撑起你目前的系统,请让它膨胀一会;
对模块化: 从一个因果论分析,结果上:程序连接起来了,并且正常运行,因:每个部分的代码正常运行了,你写的代码在程序里面了,程序找到了你的逻辑名字,比如你未定义一个变量,那么你去使用它,必然会报错,因为它压根就没有,又比如,你去调用一个对象的方法,但是他没有,那么它也必然报错,因为它压根就没有,所以你要让你分开的代码能相互认识,必然就涉及到引入,导入,告诉你的代码在哪里,组成的 部分在那里,所以模块的关键在于导入导出,为什么有导出呢,因为每一个模块本身是可以独立的,所以独立的模块有模块自由权,可以选择性的出现;
润氏吃面哲学 :我们都喜欢吃一根一根分开的拉面,而不是糊成饼的拉面, 拉面中粗细也各有不一致,同样的你的代码好不好吃,也是在于你怎么设计了.
😀进入正题项目概览
微信小程序项目文件主要由四大重要部分组成:
- JSON 配置文件
- WXML 类似于HTML
- WXSS 类似于CSS
- JS 就是JS
- WXS(可选这个不是主要必备的文件)
纵观所有的框架学习,无非就是使用工具,只是别人给的思想,给的哲学,或者给的API名字各有异同,因此对于小程序的学习或者其他的框架的学习,个人推荐的是按照项目配置穿成一条线去学习,
把控不变量,掌握共同点,借他山之石,可以攻玉
JSON 配置文件
小程序的JSON 文件主要分为:
工程配置: project.config.json 主要是对编译过程中的一些配置,和对编译器的一些配置
通常大家在使用一个工具的时候,都会针对各自喜好做一些个性化配置,例如界面颜色、编译配置等等,当你换了另外一台电脑重新安装工具的时候,你还要重新配置。
考虑到这点,小程序开发者工具在每个项目的根目录都会生成一个
project.config.json
,你在工具上做的任何配置都会写入到这个文件,当你重新安装工具或者换电脑工作时,你只要载入同一个项目的代码包,开发者工具就自动会帮你恢复到当时你开发项目时的个性化配置,其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。其他配置项细节可以参考文档 开发者工具的配置 。
应用配置:app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部tab等。主要常用字段如下:
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
entryPagePath | string | 否 | 小程序默认启动首页 |
pages | string[] | 是 | 页面路径列表 |
window | Object | 否 | 全局的默认窗口表现 |
tabBar | Object | 否 | 底部 tab 栏的表现 [其实经常会考虑自己实现] |
networkTimeout | Object | 否 | 网络超时时间 [一般设置为 5000 也就是 5s] |
functionalPages | boolean | 否 | 是否启用插件功能页,默认关闭 |
subpackages | Object[] | 否 | 分包结构配置 [一般在项目大了才会去配置,app.json整体配置类似] |
workers | string | 否 | Worker 代码放置的目录 ,小程序会单独开一个线程来允许,实现伪多线程 |
requiredBackgroundModes | string[] | 否 | 需要在后台使用的能力,主要配置项由[ “locations” , “audio”] |
plugins | Object | 否 | 使用到的插件 |
preloadRule | Object | 否 | 分包预下载规则 |
resizable | boolean | 否 | PC 小程序是否支持用户任意改变窗口大小(包括最大化窗口);iPad 小程序是否支持屏幕旋转。默认关闭 |
usingComponents | Object | 否 | 全局自定义组件配置 |
permission | Object | 否 | 小程序接口权限相关设置 |
sitemapLocation | string | 是 | 指明 sitemap.json 的位置 |
style | string | 否 | 指定使用升级后的weui样式 |
useExtendedLib | Object | 否 | 指定需要引用的扩展库 |
entranceDeclare | Object | 否 | 微信消息用小程序打开 |
darkmode | boolean | 否 | 小程序支持 DarkMode |
themeLocation | string | 否 | 指明 theme.json 的位置,darkmode为true为必填 |
lazyCodeLoading | string | 否 | 配置自定义组件代码按需注入 |
singlePage | Object | 否 | 单页模式相关配置 |
supportedMaterials | Object | 否 | 聊天素材小程序打开相关配置 |
- page.json 争对页面的一些配置,可以帮助你提前设置一些默认值,当然这个是可以通过程序进行修改的,我是指主要是样式类
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色,如 #000000 |
navigationBarTextStyle | string | white | 导航栏标题颜色,仅支持 black / white |
navigationBarTitleText | string | 导航栏标题文字内容 | |
navigationStyle | string | default | 导航栏样式,仅支持以下值: default 默认样式 custom 自定义导航栏,只保留右上角胶囊按钮。参见注 1。 |
backgroundColor | HexColor | #ffffff | 窗口的背景色 |
backgroundTextStyle | string | dark | 下拉 loading 的样式,仅支持 dark / light |
backgroundColorTop | string | #ffffff | 顶部窗口的背景色,仅 iOS 支持 |
backgroundColorBottom | string | #ffffff | 底部窗口的背景色,仅 iOS 支持 |
enablePullDownRefresh | boolean | false | 是否开启当前页面下拉刷新。 详见 Page.onPullDownRefresh |
onReachBottomDistance | number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为px。 详见 Page.onReachBottom |
pageOrientation | string | portrait | 屏幕旋转设置,支持 auto / portrait / landscape 详见 响应显示区域变化 |
disableScroll | boolean | false | 设置为 true 则页面整体不能上下滚动。 只在页面配置中有效,无法在 app.json 中设置 |
usingComponents | Object | 否 | 页面自定义组件配置 |
initialRenderingCache | string | 页面初始渲染缓存配置,支持 static / dynamic [ 一般用在起手数据量比较大的时候,结合骨架屏效果,提升用户体验 ] | |
style | string | default | 启用新版的组件样式 |
singlePage | Object | 否 | 单页模式相关配置 |
restartStrategy | string | homePage | 重新启动策略配置 |
component.json
类似于页面,一个自定义组件由
json
wxml
wxss
js
4个文件组成。要编写一个自定义组件,首先需要在json
文件中进行自定义组件声明(将component
字段设为true
可将这一组文件设为自定义组件):
属性 | 类型 | 默认值 | 必填 | 描述 |
---|---|---|---|---|
component | Boolean | true | 是 | 标识是否为组件,这个在之后讲到页面和组件的区别的时候就会提到 |
usingComponents | Object[] | {} | 否 | 组件中用到的 自定义组件配置 |
styleIsolation | String | 无 | 否 | page-isolated 表示在这个页面禁用 app.wxss ,同时,页面的 wxss 不会影响到其他自定义组件; page-apply-shared 表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式不会影响到其他自定义组件,但设为 shared 的自定义组件会影响到页面; page-shared 表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式会影响到其他设为 apply-shared 或 shared 的自定义组件,也会受到设为 shared 的自定义组件的影响。此外,小程序基础库版本 2.2.3 以上支持 addGlobalClass 选项,即在 Component 的 options 中设置 addGlobalClass: true 。这个选项等价于设置 styleIsolation: apply-shared ,但设置了 styleIsolation 选项后这个选项会失效。也就是配置是否为局部样式,默认是,不受全局影响 |
pureDataPattern | String | 无 | 否 | 从小程序基础库版本 2.10.1 开始,也可以在页面或自定义组件的 json 文件中配置 pureDataPattern (这样就不需在 js 文件的 options 中再配置)。此时,其值应当写成字符串形式: |
componentGenerics | Object | {} | 否 | 配置抽象节点,节点的 generic 引用 generic:xxx="yyy" 中,值 yyy 只能是静态值,不能包含数据绑定。因而抽象节点特性并不适用于动态决定节点名的场景. |
componentPlaceholder | Object | {} | 否 | 在使用如 分包异步化 或 用时注入 等特性时,自定义组件所引用的其他自定义组件,在刚开始进行渲染时可能处于不可用的状态。此时,为了使渲染过程不被阻塞,不可用的自定义组件需要一个 「占位组件」(Component placeholder)。基础库会用占位组件替代不可用组件进行渲染,在该组件可用后再将占位组件替换回该组件。也就是配置骨架屏的位置 |
sitemap.json 微信现已开放小程序内搜索,开发者可以通过
sitemap.json
配置,或者管理后台页面收录开关来配置其小程序页面是否允许微信索引。当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索词条触发该索引时,小程序的页面将可能展示在搜索结果中。 爬虫访问小程序内页面时,会携带特定的 user-agent:mpcrawler
及场景值:1129
。需要注意的是,若小程序爬虫发现的页面数据和真实用户的呈现不一致,那么该页面将不会进入索引中;也就是说这属于是微信的爬虫机制了,和web上的robot.txt有些类似,属于是sso优化,才会开始考虑到
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
rules | Object[] | 是 | 索引规则列表 |
rules
rules 配置项指定了索引规则,每项规则为一个 JSON 对象,属性如下所示:
属性 | 类型 | 必填 | 默认值 | 取值 | 取值说明 |
---|---|---|---|---|---|
action | string | 否 | “allow” | “allow”、“disallow” | 命中该规则的页面是否能被索引 |
page | string | 是 | “*”、页面的路径 | * 表示所有页面,不能作为通配符使用 | |
params | string | 否 | 当 page 字段指定的页面在被本规则匹配时可能使用的页面参数名称的列表(不含参数值) | ||
matching | string | 否 | “inclusive” | 参考 matching 取值说明 | 当 page 字段指定的页面在被本规则匹配时,此参数说明 params 匹配方式 |
priority | Number | 否 | 优先级,值越大则规则越早被匹配,否则默认从上到下匹配 |
matching 取值说明
值 | 说明 |
---|---|
exact | 当小程序页面的参数列表等于 params 时,规则命中 |
inclusive | 当小程序页面的参数列表包含 params 时,规则命中 |
exclusive | 当小程序页面的参数列表与 params 交集为空时,规则命中 |
partial | 当小程序页面的参数列表与 params 交集不为空时,规则命中 |
小程序框架(简单知道有什么,这些能做什么即可,再循序渐进)
小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。
实际上很多限制,做到了尽可能简单,但是开发上有特别多的限制,哎,我就受不了
整个小程序框架系统分为两部分:逻辑层(App Service)和 视图层(View)。小程序提供了自己的视图层描述语言 WXML
和 WXSS
,以及基于 JavaScript
的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统,让开发者能够专注于数据与逻辑。
视图层 (WXML ,WXSS) 需要对HTML CSS 有一个基础的概念
WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
要完整了解 WXML 语法,请参考WXML 语法参考。
用以下一些简单的例子来看看 WXML 具有什么能力:
数据绑定
之后详细的讲
1 | <!--wxml--> |
列表渲染
1 | <!--wxml--> |
条件渲染
1 | <!--wxml--> |
模板
1 | <!--wxml--> |
WXSS
WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。
WXSS 用来决定 WXML 的组件应该怎么显示。
为了适应广大的前端开发者,WXSS 具有 CSS 大部分特性。同时为了更适合开发微信小程序,WXSS 对 CSS 进行了扩充以及修改。
与 CSS 相比,WXSS 扩展的特性有:
- 尺寸单位
- 样式导入
尺寸单位
- rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
设备 | rpx换算px (屏幕宽度/750) | px换算rpx (750/屏幕宽度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
建议: 开发微信小程序时设计师可以用 iPhone6 作为视觉稿的标准。
注意: 在较小的屏幕上不可避免的会有一些毛刺,请在开发时尽量避免这种情况。
样式导入
使用@import
语句可以导入外联样式表,@import
后跟需要导入的外联样式表的相对路径,用;
表示语句结束。
示例代码:
1 | /** common.wxss **/ |
内联样式
框架组件上支持使用 style、class 属性来控制组件的样式。
- style:静态的样式统一写到 class 中。style 接收动态的样式,在运行时会进行解析,请尽量避免将静态的样式写进 style 中,以免影响渲染速度。
1 | <view style="color:{{color}};" /> |
- class:用于指定样式规则,其属性值是样式规则中类选择器名(样式类名)的集合,样式类名不需要带上
.
,样式类名之间用空格分隔。
1 | <view class="normal_view" /> |
选择器
目前支持的选择器有:
选择器 | 样例 | 样例描述 |
---|---|---|
.class | .intro | 选择所有拥有 class=“intro” 的组件 |
#id | #firstname | 选择拥有 id=“firstname” 的组件 |
element | view | 选择所有 view 组件 |
element, element | view, checkbox | 选择所有文档的 view 组件和所有的 checkbox 组件 |
::after | view::after | 在 view 组件后边插入内容 |
::before | view::before | 在 view 组件前边插入内容 |
全局样式与局部样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。
逻辑层+视图层结合WXS
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML
,可以构建出页面的结构。
注意事项
- WXS 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
- WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。
- WXS 的运行环境和其他 JavaScript 代码是隔离的,WXS 中不能调用其他 JavaScript 文件中定义的函数,也不能调用小程序提供的API。
- WXS 函数不能作为组件的事件回调。
- 由于运行环境的差异,在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。
以下是一些使用 WXS 的简单示例,要完整了解 WXS 语法,请参考WXS 语法参考。
页面渲染
1 | <!--wxml--> |
页面输出:
1 | hello world |
数据处理
1 | // page.js |
逻辑层 JS
和javascript 差不多,
JavaScript 支持情况
运行限制
基于安全考虑,小程序中不支持动态执行 JS 代码,即:
不支持使用
eval
执行 JS 代码不支持使用new Function
创建函数
new Function('return this')
除外
标准 ECMAScript 支持
小程序的 JS 执行环境 在不同平台上的执行环境存在差异,因此导致不同平台对 ECMAScript 标准的支持存在差异。
小程序基础库为了尽量抹平这些差异,内置了一份 core-js
Polyfill。core-js
可以将平台环境缺失的标准 API 补齐。
需要注意的是,平台对 ECMAScript 语法的支持差异无法抹平,当你需要使用一些高级语法时(如 async/await
时,则需要借助代码转换工具来支持这些语法。
无法被 Polyfill 的 API
以下 API 在部分低版本客户端中无法使用,请注意尽量避免使用
Proxy
对象
与标准的差异
Promise 时序差异
由于实现原因与 iOS JavaScriptCore 限制,iOS 环境下的 Promise
是一个使用 setTimeout
模拟的 Polyfill。这意味着 Promise
触发的任务为普通任务,而非微任务,进而导致 在 iOS 下的 Promise
时序会和标准存在差异。
1 | var arr = [] |
关于普通任务和微任务的区别可以自己谷歌✌
在对小程序中有什么了,以及各个部分是能做什么了,有了大概了解之后,就可以进行细节的学习了