微信小程序学习笔记

微信小程序学习笔记
Silence前言:
7月23号了,感觉读大学以来从来没有放开的耍这么久。更新的文章都是28天之前了。是时候回归正常的生活了。
小程序的运行机制
- 小程序启动可以分为两种情况,一种是冷启动,一种是热启动
冷启动:如果用户首次打开,或小程序销毁后被用户再次打开,此时小程序需要重新加载启动
热启动:如果用户已经打开过某个小程序,然后在一定时间内再次打开该小程序,此时小程序并未被销毁,知识从后台状态进入前台状态
小程序启动后,给用户展示的界面就是前台,此时小程序处于
前台
当用户回复微信消息的时候,小程序并没有被关闭,而是进入了
后台
状态,当用户再次打开的时候就又重新进入前台
状态挂起:小程序进入
后台
状态一段时间后(5秒),微信停止小程序JS线程执行,小程序进入挂起状态,当开发者使用了音乐播放或者地理位置等能力时小程序可以在后台持续运行,不会进入到挂起状态销毁:如果用户很久没有使用小程序,或者系统资源紧张,小程序会被销毁,即完全终止运行。当小程序进入后台并被挂起后如果很长时间(目前是30分钟)都未再次进入前台,小程序会被销毁当小程序占用系统资源过高,可能会被系统销毁或被微信客户端主动回收
小程序的更新机制
在访问小程序时,微信会将小程序代码包缓存到本地
开发者在发布了新的小程序版本后,微信客户端会检查本地缓存的小程序有没有新版本,,并进行小程序代码包的更新。
小程序的更新机制有两种:启动时更新和启动时异步更新
定期检查发现版本更新
微信运行时,会定期检查最近使用的小程序是否有更新。如果有更新,下次小程序启动时会同步进行更新,更新到最新版本后再打开小程序,尽可能保证用户能够尽快使用小程序的最新版本。
用户长时间未使用小程序
用户长时间未使用小程序时,为保障小程序版本的实时性,会强制同步检查版本更新,更新到最新版本后再打开小程序。
若用户处于弱网环境、下载最新版本失败等情况下,仍会启动本地的较低版本。
启动时异步更新
即使启动前未发现更新,小程序每次冷启动时,都会异步检查是否有更新版本。如果发现有新版本,将会异步下载新版本的代码包。但当次启动仍会使用客户端本地的旧版本代码,即新版本的小程序需要等下一次冷启动才会使用。
开发者手动触发更新
在启动时异步更新的情况下,如果开发者希望立刻进行版本更新,可以使用 wx.getUpdateManager API 进行处理。在有新版本时提示用户重启小程序更新新版本。
小程序 wx.getUpdateManager API使用示例
1 | onLaunch(){ |
小程序生命周期介绍
应用生命周期
小程序的生命周期是指小程序从启动到销毁的整个过程
一个完整的小程序的生命周期由应用生命周期
,页面生命周期
和组件生命周期
三部分组成
小程序生命周期伴随者一些函数,这些函数由小程序框架本身提供,被称为生命周期函数,生命周期函会按照顺序依次自动触发调用帮助程序员在特定的时机执行特定的操作,辅助程序员完成一些比较复杂的逻辑
应用生命周期伴随者一些函数,我们称为应用生命周期函数
,应用生命周期函数需要在app.js 文件的APP() 方法中定义
APP()方法必须在app.js中进行调用,主要用来注册小程序
应用生命周期函数由 onLanunch
, onShow
, onHide
三个函数组成
这里在执行了onHide后,如果长时间未使用,被销毁后。onHide 跳转到小程序的启动(冷启动)
1 | App({ |
页面生命周期
页面生命周期函数就是指小程序页面从加载-运行-销毁的整个过程
页面生命周期函数需要在Page()方法进行定义
- onLoad:首次进入页面加载时触发,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
- onShow:加载完成后、后台切到前台或重新进入页面时触发(页面跳转的时候) -> onHide(页面隐藏)
- onReady:页面首次渲染完成时触发
- onHide:从前台切到后台或进入其他页面触发
- onUnload:页面卸载时触发(页面销毁)
1 | Page({ |
小程序API
- 小程序提供的API几乎都挂载在wx对象下,wx对象实际上就是小程序的宿主环境微信提供的全局对象
小程序API分类
- 异步API:通常都接受一个objec类型的参数
- 同步API:约定以Sync结尾
- 时间监听API:约定以on开头
异步API支持 callback & Promise 两种调用方式:
- 当接口参数Object 对象中不包含 succsess/fail/complete 时将默认返回Promise
- 部分接口如 request , uploadFile 本身就有返回值,因此不支持Promise风格的调用方式,他们的promisify需要开发者自行封装
网络请求
这里如果要发起网络请求需要在域名列表中配置对应的域名,不然会报以下的错误
配置教程: 😎👉点击链接
也可以直接关闭校验
网络请求示例代码:
1 |
|
1 | Page({ |
界面交互-Loading
小程序提供了一些用于界面交互的API ,例如:loading提示框,消息提示框,模态对话框等API loading提示框常配合网络请求来使用,用于增加用户体验,对应的API有两个:
wx.showLoading () 显示提示框
wx.hideLoading() 关闭loading提示框
1 | Page({ |
界面交互-模态对话框-消息提示框
wx.showModal():模态对话框,常用于询问用户是否执行一些操作。
例如:询问用户是否退出登录、是否删除该商品等。
1 | <button type="primary" bind:tap="delHandler"> 删除商品</button> |
1 | //删除商品 |
wx.showToast():消息提示框,根据用户的某些操作来告知操作的结果。
例如:退出成功给用户提示,提示删除成功等。
1 | // 删除商品 |
本地存储
对象类型的数据,可以直接进行存储获取,无需使用 JSON.stringify()、JSON.parse()转换。
1 | <button size="mini" plain type="warn" bind:tap="setStorage">存储</button> |
1 | Page({ |
路由与通信
在小程序中实现页面的跳转,有两种方式:
- 声明式导航:navigator组件
- 编程式导航:使用小程序提供的API
1 | Page({ |
上拉加载
上拉加载是小程序中常见的一种加载方式,当用户滑动页面到底部时,会自动加载更多的内容,以便用户继续浏览小程序中实现上拉加载的方式:
- 在app.json或者page.json中配置距离页面底部距离:onReachBottomDistance;默认50px。
- 在页面.js中定义onReachBottom事件监听用户上拉加载。
随机找到或者创建一个空页面,我这里使用之前的页面将其中的内容注释掉,找到.json文件
1 | { |
1 | Page({ |
下拉加载
下拉刷新是小程序中常见的一种刷新方式,当用户下拉页面时,页面会自动刷新,以便用户获取最新的内容。
小程序中实现上拉加载更多的方式:
在 app.json 或者 page.json 中开启允许下拉,同时可以配置 窗口、loading 样式等。
在 页面.js 中定义 onPullDownRefresh 事件监听用户下拉刷新。
1 | // 监听用户下拉刷新 |
需要注意一点的是,下拉刷新以后,loading效果有可能不会回弹回去,一次我们可以添加:
1 | // 下拉刷新以后,loading效果有可能不会回弹回去 |
自定义组件
小程序目前已经支持组件化开发,可以将页面中的功能模块抽取成自定义组件,以便在不同的页面中重复使用;
也可以将复杂的页面拆分成多个低耦合的模块,有助于代码的维护
开发中常见的组件有两种:
- 公共组件:将页面内的功能模块抽取成自定义组件,以便在不同的页面中重复使用。(建议放在项目根目录的components文件夹中)
- 页面组件:将复杂的页面拆分成多个低耦合的模块,有助于代码维护(建议放在对应页面的目录下)
建议:一个组件一个文件夹
创建和注册组件
components中新建文件夹,然后右键文件夹选择新建Component
- 注册组件
开发中常见的组件主要分为公共组件和页面组件两种,因此注册组件的方式也分为两种:
- 全局注册:在app.json 文件中配置usingComponents进行注册,
注册后可以在任意页面使用
- 局部注册:在页面的json文件中配置usingComponents进行注册,
注册后只能在当前页面使用
在usingCompinents中进行组件注册时,需要提供 自定义组件的组件名 和 自定义组件文件路径
如果是公共组件,建议将其放在小程序的目录下的 components
文件夹中
如果是页面组件,建议将其放在小程序对应页面目录下,当然你也可以放到页面的 components
文件夹中
同时建议:一个组件一个文件夹,文件夹名称和组件名称保持一致
📌 注意事项:
- 自定义组件的需要在
json
文件中需要配置component
字段设为true
- 自定义组件通过
Component
构造器进行构建,在构造器中可以指定组件的属性、数据、方法等
创建组件
创建组件的步骤很简单,以公共组件为例,创建的步骤如下:
在小程序的目录下新建
components
文件夹在
components
文件夹上,点击右键,选择新建文件夹
,然后输入文件夹名称,我们建议文件夹的名称和组件的名称保持一致,这样方便后期对组件进行维护。我们这里新的的组件名称叫做:custom-checkbox
在新建的组件文件夹上,点击右键,选择
新建 Component
,然后输入组件的名称,组件的名称建议和文件夹保持一致此时就已经创建了一个功能组件
使用自定义组件
开发中常见的组件主要分为 公共组件 和 页面组件 两种,因此注册组件的方式也分为两种:
- 全局注册:在
app.json
文件中配置usingComponents
节点进行引用声明,注册后可在任意组件使用 - 局部注册:在页面的
json
文件中配置usingComponents
节点进行引用声明,只可在当前页面使用
在配置 usingComponents
节点进行引用声明时,需要提供自定义组件的标签名和对应的自定义组件文件路径,语法如下:
1 | { |
这样,在页面的 wxml
中就可以像使用基础组件一样使用自定义组件。节点名即自定义组件的标签名,节点属性即传递给组件的属性值。
1 | { |
1 | <!--pages/index/index.wxml--> |
自定义组件-数据和方法
在组件的 .js 中,需要调用 Component
方法创建自定义组件,Component
中有以下两个属性:
data
数据:组件的内部数据
methods
方法:在组件中事件处理程序需要写到 methods
中才可以
自定义组件-属性
属性 Properties 是指组件的对外属性,主要用来接收组件使用者传递给组件内部的数据,和 data 一同用于组件的模板渲染
📌 注意事项:
- 设置属性类型需要使用 type 属性,属性类型是必填项,value 属性为默认值
- 属性类型可以为 String、Number、Boolean、Object、Array ,也可以为 null 表示不限制类型
1 | Component({ |
组件 wxml 的 slot
在使用基础组件时,可以给组件传递子节点传递内容,从而将内容展示到页面中,自定义组件也可以接收子节点内容
只不过在组件模板中需要定义 <slot />
节点,用于承载组件引用时提供的子节点
默认情况下,一个组件的 wxml 中只能有一个 slot 。需要使用多 slot 时,可以在组件 js 中声明启用。
同时需要给 slot 添加 name 来区分不同的 slot,给子节点内容添加 slot 属性来将节点插入到 对应的 slot 中
组件样式以及注意事项
类似于页面,自定义组件拥有自己的 wxss
样式,组件对应 wxss
文件的样式,只对组件wxml内的节点生效。
编写组件样式时,需要注意以下几点:
app.wxss 或页面的 wxss 中使用了标签名(view)选择器(或一些其他特殊选择器)来直接指定样式
这些选择器会影响到页面和全部组件,通常情况下这是不推荐的做法组件和引用组件的页面不能使用 id 选择器(#a)、属性选择器([a]) 和 标签名选择器,请改用 class 选择器
组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用
子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
继承样式,如 font 、 color ,会从组件外继承到组件内。
除继承样式外, 全局中的样式、组件所在页面的的样式对自定义组件无效 (除非更改组件样式隔离选项)
1 | #a { } /* 在组件中不能使用 */ |
落地代码:
➡️ custom02.wxml
1 | <text id="content" class="content son"> |
➡️ custom02.wxss
1 | /* components/custom02/custom02.wxss */ |
➡️ cate.wxml
1 | <view class="custom parent"> |
➡️ cate.wxss
1 | /* pages/cate/cate.wxss */ |
➡️ app.wxss
1 | /* .label { |
组件样式隔离
默认情况下,自定义组件的样式只受到自定义组件 wxss 的影响。除非以下两种情况:
app.wxss
或页面的wxss
中使用了标签名(view)选择器(或一些其他特殊选择器)来直接指定样式,这些选择器会影响到页面和全部组件。通常情况下这是不推荐的做法。指定特殊的样式隔离选项
styleIsolation
1
2
3
4
5Component({
options: {
styleIsolation: 'isolated'
}
})
styleIsolation
选项它支持以下取值:
isolated
表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);apply-shared
表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;shared
表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了apply-shared
或shared
的自定义组件。
落地代码:
➡️ custom03.wxml
1 | <!--components/custom03/custom03.wxml--> |
➡️ custom03.wxss
1 | /* components/custom03/custom03.wxss */ |
➡️ custom03.js
1 | // components/custom03/custom03.js |
➡️ cate.wxml
1 | <custom03 /> |
➡️ cate.wxss
1 | .label { |
拓展-小程序修改checkbox样式
知识点:
技巧:在官方文档,找到官方提供的案例,审查元素,就能看到对应的类名
📌 注意事项
- .custom-checkbox .wx-checkbox-input {}:复选框没有选中时默认的样式
- .custom-checkbox .wx-checkbox-input-checked {}: 复选框选中时默认的样式
- .custom-checkbox .wx-checkbox-input.wx-checkbox-input-checked:before {}:复选框选中时 √ 样式
这几个类名,在全局样式文件、页面样式文件都可以对修改复选框样式,
但是在自定义组件内部使用的时候,需要添加 styleIsolation: 'shared' 属性
落地代码:
➡️ components/custom-checkbox/custom-checkbox.wxss
1 | /* 复选框组件是公共组件 */ |
➡️ components/custom-checkbox/custom-checkbox.js
1 | Component({ |
➡️ index.wxss
1 | /* 组件使用者修改复选框的样式 */ |
数据监听器
知识点:
数据监听器可以用于监听和响应任何属性和数据字段的变化,有时,需要在一些数据字段被 setData 设置时,需要执行一些操作。那么就可以使用 observers
数据监听器来实现。语法如下:
1 | Component({ |
组件间通信与事件
父往子传值
知识点:
父组件如果需要向子组件传递指定属性的数据,在 WXML 中需要使用数据绑定的方式
与普通的 WXML 模板类似,使用数据绑定,这样就可以向子组件的属性传递动态数据。
父组件如果需要向子组件传递数据,只需要两个步骤:
1.在父组件 WXML 中使用 数据绑定 的方式向子组件传递动态数据
2.子组件内部使用 properties 接收父组件传递的数据即可
知识点代码:
1 | <!-- 引用组件的页面模板 --> |
在组件内部,需要在 Component
构造器中通过 properties
接收传递的数据,接收方式有两种:
1 | Component({ |
在子组件中也可以通过 this.setData()
对 properties
中的数据进行修改,但是一般不建议修改
1 | // components/custom01/custom01.js |
复选框组件案例:
➡️ index.js
1 | Page({ |
➡️ index.wxml
1 | <custom-checkbox |
➡️ components/custom-checkbox/custom-checkbox.js
1 | Component({ |
➡️ components/custom-checkbox/custom-checkbox.wxml
1 | <!--components/custom-checkbox/custom-checkbox.wxml--> |
子往父传值
子组件如果需要向父组件传递数据,可以通过小程序提供的事件系统实现传递传递,可以传递任意数据。
事件系统是组件间通信的主要方式之一,自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件,流程如下:
- 自定义组件触发事件时,需要使用
triggerEvent
方法发射一个自定义的事件 - 自定义组件标签上通过 bind 方法监听发射的事件
触发事件:
1 | <!-- 在自定义组件中 --> |
1 | // components/custom05/custom05.js |
监听事件:
1 | <view>{{ num }}</view> |
1 | Page({ |
复选框组件案例:
➡️ components/custom-checkbox/custom-checkbox.js
1 | Component({ |
➡️ index.html
1 | <custom-checkbox |
➡️ index.js
1 | Page({ |
组件生命周期
组件的生命周期:指的是组件自身的一些钩子函数,这些函数在特定的时间节点时被自动触发
组件的生命周期函数需要在 lifetimes
字段内进行声明
最重要的生命周期是 created
attached
detached
包含一个组件生命周期流程的最主要时间点
定义段 | 描述 |
---|---|
created |
在组件实例刚刚被创建时执行,注意此时不能调用 setData (还没有对模板解析) |
attached |
在组件实例进入页面节点树时执行 (模板已经解析完毕,并且挂载到页面上) |
ready | 在组件布局完成后执行 |
moved | 在组件实例被移动到节点树另一个位置时执行 |
detached |
在组件实例被从页面节点树移除时执行 (组件被销毁了) |
【组件实例刚刚被创建好时】,
created
生命周期被触发。此时,组件数据this.data
就是在Component
构造器中定义的数据data
。 此时还不能调用setData
。 通常情况下,这个生命周期只应该用于给组件this
添加一些自定义属性字段。【在组件完全初始化完毕】、进入页面节点树后,
attached
生命周期被触发。此时,this.data
已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。【在组件离开页面节点树后】,
detached
生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则detached
会被触发。
1 | Component({ |
组件所在页面的生命周期
组件还有一些特殊的生命周期,这类生命周期和组件没有很强的关联
主要用于组件内部监听父组件的展示、隐藏状态,从而方便组件内部执行一些业务逻辑的处理
组件所在页面的生命周期有 4 个: show、 hide、 resize、 routeDone,需要在 pageLifetimes
字段内进行声明
1 | // components/custom06/custom06.js |
小程序生命周期总结
小程序冷启动,钩子函数执行的顺序
保留当前页面(navigate) 以及 关闭当前页面(redirect)
切后台 以及 切前台(热启动)
拓展:使用 Component 构造页面
Component 方法用于创建自定义组件
小程序的页面也可以视为自定义组件,因此页面也可以使用 Component 方法进行创建,从而实现复杂的页面逻辑开发
📌 注意事项:
要求对应 json 文件中包含 usingComponents 定义段
页面使用 Component 构造器创建,需要定义与普通组件一样的字段与实例方法
页面 Page 中的一些生命周期方法(如 onLoad() 等以“on”开头的方法),在 Component 中要写在 methods 属性中才能生效
组件的属性 Properties 可以用于接收页面的参数,在 onLoad() 中可以通过 this.data 拿到对应的页面参数
落地代码:
1 | Component({ |
拓展:behaviors
如果需要注册一个 behavior
,需要借助 Behavior()
方法,接受一个 Object
类型的参数
1 | // my-behavior.js |
使用 behavior:
1 | // my-component.js |
组件和它引用的 behavior 中可以包含同名的字段,对这些字段的处理方法如下:
如果有同名的属性或方法,采用 “就近原则”,组件会覆盖 behavior 中的同名属性或方法
如果有同名的数据字段且都是对象类型,会进行对象合并,其余情况会 采用 “就近原则” 进行数据覆盖
生命周期函数和 observers 不会相互覆盖,会是在对应触发时机被逐个调用,也就是都会被执行
详细的规则:同名字段的覆盖和组合规则
拓展:外部样式类
默认情况下,组件和组件使用者之间如果存在相同的类名不会相互影响,组件使用者如果想修改组件的样式,需要就解除样式隔离,但是解除样式隔离以后,在极端情况下,会产生样式冲突、CSS 嵌套太深等问题,从而给我们的开发带来一定的麻烦。
外部样式类:在使用组件时,组件使用者可以给组件传入 CSS 类名,通过传入的类名修改组件的样式。
如果需要使用外部样式类修改组件的样式,在 Component 中需要用 externalClasses 定义若干个外部样式类。
外部样式类的使用步骤:
1.在 Component 中用 externalClasses 定义段定义若干个外部样式类
2.自定义组件标签通过 属性绑定 的方式提供一个样式类,属性是 externalClasses 定义的元素,属性值是传递的类名
3.将接受到的样式类用于自定义组件内部
📌注意事项:
在同一个节点上使用普通样式类和外部样式类时,两个类的优先级是未定义的
因此需要添加 !important 以保证外部样式类的优先级
落地代码:
➡️ custom09.js
1 | // components/custom09/custom09.js |
➡️ custom09.wxml
1 | <!-- 在同一个节点上,如果存在外部样式类 和 普通的样式类 --> |
➡️ custom09.wxss
1 | .box { |
➡️ profile.wxml
1 | <!-- 属性是在 externalClasses 里面定义的元素 --> |
➡️ profile.wxss
1 | /* pages/index/index.wxss */ |
npm 支持
构建 npm
目前小程序已经支持使用 npm 安装第三方包,但是这些 npm 包在小程序中不能够直接使用,必须得使用小程序开发者工具进行构建后才可以使用。
为什么得使用小程序开发者工具需要构建呢❓
因为 node_modules
目录下的包,不会参与小程序项目的编译、上传和打包,因此。在小程序项目中要想使用 npm 包,必须走一遍 构建 npm 的过程。
在构建成功以后,默认会在小程序项目根目录,也就是 node_modules
同级目录下生成 miniprogram_npm
目录,里面存放这构建打包后的 npm 包,也就是小程序运行过程中真正使用的包
微信开发者工具如何构建❓
我们以使用 Vant Weapp 小程序 UI 组件库为例,来说明小程序如何安装和构建 npm,构建 npm 的步骤如下:
- 初始化
package.json
- 通过
npm
安装项目依赖 - 通过微信开发者工具构建
npm
📌 注意事项:
小程序运行在微信内部,因为运行环境的特殊性,这就导致 并不是所有的包都能够在小程序使用
我们在小程序中提到的包指专为小程序定制的 npm 包,简称小程序 npm 包,在使用包前需要先确定该包是否支持小程序
开发者如果需要发布小程序包,需要参考官方规范:https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html#发布-npm-包
构建的详细步骤:
初始化
package.json
,这一步至关重要,要不然后续的步骤都很难进行下去1
npm init -y
通过 npm 安装
@vant/weapp
包1
npm i @vant/weapp -S --production
构建 npm
修改 app.json
到这一步 npm 的构建已经完成了,但是
Vant
组件库,会和基础组件的样式冲突,因此我们需要继续往下配置将 app.json 中的
"style": "v2"
去除,小程序的新版基础组件强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱。在页面中使用
vant
提供的小程序组件,这里以Button
按钮组件为例- 在
app.json
或index.json
中引入组件 - 在
app.json
中注册的组件为全局注册,可以在任意组件中进行使用 - 在
index.json
中注册组件为组件组件,只能在当前组件中进行使用 - 按照组件提供的使用方式,在页面中使用即可
1
2
3"usingComponents": {
"van-button": "@vant/weapp/button/index"
}1
2
3
4
5<van-button type="default">默认按钮</van-button>
<van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button>- 在
页面预览效果
自定义构建 npm
在实际的开发中,随着项目的功能越来越多、项目越来越复杂,文件目录也变的很繁琐,为了方便进行项目的开发,开发人员通常会对目录结构进行调整优化,例如:将小程序源码放到 miniprogram 目录下。
但是在调整目录以后,我们按照上一小节 Vant Weapp
的构建流程进行构建,发现没有构建成功,并且弹出构建失败的弹框
[错误提示翻译意思是] :没有找到可以构建的 npm 包
[解决方式]:
- 请确认需要参与构建的 npm 都在
miniprogramRoot
目录内 - 配置
project.config.json
的packNpmManually
和packNpmRelationList
进行构建
产生这个错误的原因是因为小程序的构建方式有两种:
- 默认构建
npm
- 自定义构建
npm
默认构建 npm
默认情况下,不使用任何模版,miniprogramRoot
是小程序项目根目录,在 miniprogramRoot
内正确配置了 package.json
并执行 npm install
之后,在项目的根目录下就有 node_modules
文件夹,然后对 node_modules
中的 npm
进行构建,其构建 npm 的结果是,为 package.json
对应的 node_modules
构建一份 miniprogram_npm
,并放置在对应 package.json
所在目录的子目录中
自定义构建 npm
与默认的构建 npm 方式
不一样,自定义构建 npm 的方式为了更好的优化目录结构,更好的管理项目中的代码。
需要开发者在 project.config.json
中指定 node_modules
的位置 和 目标 miniprogram_npm
的位置
在project.config.json
中详细的配置流程和步骤如下:
- 新增
miniprogramRoot
字段,指定调整后了的小程序开发目录 - 新增
setting.packNpmManually
设置为true
,开启指定node_modules
的位置以及构建成功后文件的位置 - 新增
setting.packNpmRelationList
项,指定packageJsonPath
和miniprogramNpmDistDir
的位置packageJsonPath
表示node_modules
源对应的package.json
miniprogramNpmDistDir
表示node_modules
的构建结果目标位置
1 | { |
落地代码:
将小程序核心源码放到 miniprogram 目录下
在
project.config.json
中进行配置1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16{
"compileType": "miniprogram",
+ "miniprogramRoot": "miniprogram/",
+ "setting": {
+ "packNpmManually": true,
+ "packNpmRelationList": [
+ {
+ "packageJsonPath": "./package.json",
+ "miniprogramNpmDistDir": "./miniprogram"
+ }
+ ]
+ }
// coding... 其他配置项
}
Vant 组件的使用方式
Vant Weapp 是有赞前端团队开源的小程序 UI 组件库,基于微信小程序的自定义组件开发,可用来快速搭建小程序项目。
在使用 Vant 提供的组件时,只需要两个步骤:
1.将组件在 app.json 中进行全部注册 或者 index.json 中进行局部注册
2.在引入组件后,可以在 wxml 中直接使用组件
在前面我们以 image
组件为例,讲解 Vant
组件库的基本使用方式
首先还是需要将先将组件进行引入,这里我们进行全局引入
1 | // app.json |
引入组件后,可以在 wxml 中直接使用组件
1 | <van-image width="100" height="100" src="https://img.yzcdn.cn/vant/cat.jpeg" /> |
如果我们想给 van-field
添加一些属性,这时候我们需要查看 API 手册
1 | <van-image width="100" height="100" round src="/assets/Jerry.png"/> |
如果我们想给 van-field
添加一些事件,这时候我们需要查看 事件 手册
1 | <van-image |
1 | Page({ |
如果我们想给 van-field
添加一些插槽,这时候我们需要查看 slot 手册
1 | <van-image |
如果我们想给 van-field
添加一些外部样式类,这时候我们需要查看 外部样式类 手册
1 | <van-image |
1 | /* pages/index/index.wxss */ |
Vant 组件的样式覆盖
Vant Weapp
基于微信小程序的机制,为开发者提供了以下 3 种修改组件样式的方法
- 解除样式隔离:在页面中使用 Vant Weapp 组件时,可直接在页面的样式文件中覆盖样式
- 使用外部样式类:需要注意普通样式类和外部样式类的优先级是未定义的,需要添加 !important 保证外部样式类的优先级
- 使用 CSS 变量:在页面或全局对多个组件的样式做批量修改以进行主题样式的定制
第 1 种:解除样式隔离
Vant Weapp
的所有组件都开启了addGlobalClass: true
以接受外部样式的影响,因此我们可以通过审核元素的方式获取当前元素的类名,然后复制到组件的 .wxss
中进行修改
第 2 种:使用外部样式类
Vant Weapp
开放了大量的外部样式类供开发者使用,具体的样式类名称可查阅对应组件的 “外部样式类” 部分。
需要注意的是普通样式类和外部样式类的优先级是未定义的,因此使用时请添加!important
以保证外部样式类的优先级。
第 3 种:使用 CSS 变量
Vant Weapp
可以通过 CSS
变量的方式多个组件的样式做批量修改。CSS
的变量基础用法如下:
- 声明一个自定义属性,属性名需要以两个减号(
--
)开始,属性值则可以是任何有效的 CSS 值
1 | /* app.wxss */ |
- 使用一个局部变量时用
var()
函数包裹以表示一个合法的属性值
1 | /* 声明局部的变量 */ |
- 页面中使用该变量
1 | <view class="container"> |

也可以在按钮身上添加类名:
1 | <!-- 使用 CSS 变量:如果需要再多个页面或者一个组件中 需要批量修改组件、定制主题 --> |
1 | .my-button { |
分包加载
什么是分包加载
什么是分包加载 ❓
小程序的代码通常是由许多页面、组件以及资源等组成,随着小程序功能的增加,代码量也会逐渐增加,体积过大就会导致用户打开速度变慢,影响用户的使用体验。
分包加载是一种小程序优化技术。将小程序不同功能的代码,分别打包成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载,在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。每个分包可以包含多个页面、组件、样式和逻辑等。当小程序需要使用某个分包时,才会加载该分包中的代码。
主包:包含默认启动页面 / TabBar 页面 以及 所有分包都需用到公共资源的包
分包:根据开发者的配置进行划分出来的子包
小程序分包后如何加载
在小程序启动时,默认会下载主包并启动主包内页面,在用户访问分包内某个页面时,微信客户端才会把对应分包下载下来,下载完成后再进行展示。
目前小程序分包大小有以下限制:**
- 整个小程序所有分包大小不超过 20MB
- 单个分包/主包大小不能超过 2MB
📌 注意事项:
整个小程序所有分包大小可能会随时调整,截止到目前整个小程序所有分包大小不超过 20M
###2. 分包的基本使用
知识点:
在进行分包加载之前,需要对小程序的业务逻辑进行分析,将代码划分成多个模块。每个模块应该有一个明确的功能,并与其他模块之间有明确的依赖关系
需要按照功能拆分分包,并且每个分包都需要与其他包有依赖关系(可以通过 a 分包跳转到 b 分包)
开发者在小程序的配置文件 app.json
中,通过 subPackages
或者 subpackages
字段声明项目分包结构。
每个分包需要指定 root
字段、name
字段和 pages
字段
root
字段指定了分包的根目录,该目录下的所有文件都会被打包成一个独立的包name
字段为分包的名称,用于在代码中引用该分包pages
字段指定了该分包中包含的页面,可以使用通配符*
匹配多个页面
落地代码:
1 | { |
打包和引用原则(注意事项)
打包原则:
tabBar 页面必须在主包内
最外层的 pages 字段,属于主包的包含的页面
按 subpackages 配置路径进行打包,配置路径外的目录将被打包到主包中
分包之间不能相互嵌套,subpackage 的根目录不能是另外一个 subpackage 内的子目录
引用原则:
主包不可以引用分包的资源,但分包可以使用主包的公共资源
分包与分包之间资源无法相互引用, 分包异步化时不受此条限制
独立分包的配置
什么是独立分包:
独立分包:独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。
从独立分包中页面进入小程序时,不需要下载主包,但是当用户进入普通分包或主包内页面时,主包才会被下载 !
开发者可以将功能相对独立的页面配置到独立分包中,因为独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
如果是独立分包,不需要下载主包,直接就能够访问,独立分包是自己独立运行的
而如果是其他分包,需要先下载主包,通过路径访问,才能加载对应路径的分包
📌 注意事项:
独立分包中不能依赖主包和其他分包中的资源
主包中的 app.wxss 对独立分包无效
App 只能在主包内定义,独立分包中不能定义 App,会造成无法预期的行为
如何配置独立分包:
开发者在app.json
中找到需要配置为独立分包的subpackages
字段
在该字段配置项中定义independent
字段声明对应分包为独立分包。
落地代码:
1 | { |
分包预下载
知识点:
分包预下载是指访问小程序某个页面时,预先下载分包中的代码和资源,以提高用户的使用体验。当用户需要访问分包中的页面时,已经预先下载的代码和资源可以直接使用,通过分包预下载加快了页面的加载速度和显示速度。
小程序的分包预下载需要在 app.json
中通过 preloadRule
字段设置预下载规则。preloadRule
是一个对象,对象的 key
表示访问哪个路径时进行预加载,value
是进入此页面的预下载配置,具有两个配置项:
字段 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
packages | StringArray | 是 | 无 | 预下载的分包名称,进入页面后预下载分包的 root 或 name __APP__ 表示主包。 |
network | String | 否 | wifi | 在指定网络下预下载, 可选值为: all : 不限网络 wifi : 仅wifi下预下载 |
1 | { |
落地代码:
1 | { |
小程序开发能力
获取用户头像
当小程序需要让用户完善个人资料时,我们可以通过微信提供的头像、昵称填写能力快速完善。如图:
想使用微信提供的头像填写能力,需要两步:
- 将 button 组件
open-type
的值设置为chooseAvatar
- 当用户选择需要使用的头像之后,可以通过
bindchooseavatar
事件回调获取到头像信息的临时路径。
1 | <!-- 给 button 添加 open-type 属性,值为 chooseAvatar --> |
落地代码:
1 | <view class="avatar"> |
1 | Page({ |
获取用户昵称
知识点:
当小程序需要让用户完善个人资料时,我们可以通过微信提供的头像、昵称填写能力快速完善。如图:
想使用微信提供的昵称填写能力,需要三步:
通过 form 组件中包裹住 input 以及 form-type 为 submit 的 button 组件
需要将 input 组件 type 的值设置为 nickname,当用户输入框输入时,键盘上方会展示微信昵称
给 form 绑定 submit 事件,在事件处理函数中通过事件对象获取用户昵称
落地代码:
1 | <!-- 需要使用 form 组件包裹住 input 以及 button 组件 --> |
1 | Page({ |
转发功能
转发功能,主要帮助用户更流畅地与好友分享内容和服务
想实现转发功能,有两种方式:
页面 js 文件 必须声明 onShareAppMessage 事件监听函数,并自定义转发内容。只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮
通过给 button 组件设置属性 open-type=“share“ ,在用户点击按钮后触发 Page.onShareAppMessage 事件监听函数
落地代码:
1 | <!--pages/cate/cate.wxml--> |
1 | Page({ |
分享到朋友圈
小程序页面默认不能被分享到朋友圈,开发者需主动设置“分享到朋友圈”才可以,实现分享到朋友圈需满足两个条件:
页面 必须 设置允许“发送给朋友”,页面 js 文件声明 onShareAppMessage 事件监听函数
页面 必须 需设置允许“分享到朋友圈”,页面 js 文件声明 onShareTimeline 事件监听函数
落地代码:
1 | Page({ |
手机号验证组件
手机验证组件,用于帮助开发者向用户发起手机号申请,必须经过用户同意后,才能获得由平台验证后的手机号,进而为用户提供相应服务
手机号快速验证组件:平台会对号码进行验证,但不保证是实时验证
1
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
手机号实时验证组件:在每次请求时,平台均会对用户选择的手机号进行实时验证
1
2
3
4<button
open-type="getRealtimePhoneNumber"
bindgetrealtimephonenumber="getrealtimephonenumber"
/>
📌注意事项:
1.目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)
2.两种验证组件需要付费使用,每个小程序账号将有 1000 次体验额度
其他要求和注意事项,参考文档:
落地代码:
1 | <!--pages/cart/cart.wxml--> |
1 | Page({ |
客服能力
小程序为开发者提供了客服能力,同时为客服人员提供移动端、网页端客服工作台便于及时处理消息
使用方式:
需要将 button 组件 open-type 的值设置为 contact,当用户点击后就会进入客服会话
1
<button type="warn" plain open-type="contact">联系客服</button>
在微信公众后台,绑定后的客服账号,可以登陆 网页端客服 或 移动端小程序 客服接收、发送客服消息
上线发布
假设我们目前已经使用微信开发者工具,按照小程序的开发规范完成了小程序的全部的全部开发工作,并且完成了本地测试,
这时候我们需要开发对小程序进行发布,小程序上线的流程如下:
开发版本:点击开发者工具上传后的版本,开发版本只保留每人最新的一份上传的代码,是供开发者和团队测试和调试的版本
体验版本:小程序开发者可以将开发版本转换为体验版本,由测试人员以及产品经理进行测试与体验,确认没问题可提交审核
审核版本:小程序开发者可以将开发版本转换为审核版本,由微信的审核团队进行审核,审核周期为1~7天,审核通过可提交发布
线上版本:通过微信小程序平台审核,并由开发者提交发布的正式版本,线上版本是用户可以正常使用的小程序版本
小程序开发成员在开发者工具中点击 上传
按钮,在弹出的界面中选择更新类型、版本号、项目备注,就能够将小程序代码上传至微信公众号后台审核。
在登录到微信公众后台以后,点击左侧的 管理
➡ 版本管理
,就能查看小程序的四个个版本