基础篇
开发者都有对应的开发 ID

安装微信开发者工具
微信官方文档,工具,下载,稳定版
关闭代理模式,以防网络原因,出现问题
代码构成
- pages:存放所有小程序页面
- utils:存放工具性质的模块
- app.js 小程序项目入口文件
- app.json 小程序项目全局配置文件
- app.wxss 小程序项目全局样式文件
- project.config.json:项目的配置文件
- sitemap.json 配置小程序及其页面是否允许被微信索引

页面构成
页面在 pages 中有四块
- index.js:页面脚本文件
- index.json:页面配置文件,如外观,表现
- index.wxml:页面模板结构文件
- index.wxss:当前页面样式文件
最终会编译成一个页面

JSON 配置文件
JSON 是一种数据格式,通过不同的 .json 配置文件,可以对小程序项目进行不同级别的配置。
- app.json 是当前小程序的全局配置,包含所有页面路径,窗口外观,界面表现,底部tab
- pages:记录小程序所有页面的路径
- window:全局定义所有页面的背景色,文字颜色等
- style:全局定义小程序组件所使用的样式版本(默认v2最新版本)
- sitemapLocation:指定 sitemap.json 的位置
json
{
"pages": [
"pages/index/index",
"pages/logs/logs"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle": "black"
},
"style": "v2",
"sitemapLocation": "sitemap.json",
- project.config.json 是项目配置文件,用来记录我们对小程序开发工具所做的个性化配置
- setting 中保存了编译相关的配置
- projectname 中保存的是项目名称(任意定制)
- appid 中保存的是小程序的账号 ID
- description:说明这是配置文件
- sitemap.json 微信索引SEO
当开发者允许微信索引时,微信会通过爬虫的形式,为小程序的页面内容建立索引。当用户的搜索关键字和页面的索引匹配成功的时候,小程序的页面将可能展示在搜索结果中。
- page: *:表示所有页面都可以被微信索引
- action:allow = 允许, disallow:不允许
json
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}
- 页面的 .json 配置文件
对本页面的窗口外观进行配置,页面中的配置项会覆盖 app.json 的 window 中相同的配置项
修改首页
默认会把 app.json 文件的pages第一行作为首页
json
{
"pages": [
"pages/list/index", // 第一个是首页
"pages/index/index",
"pages/logs/logs"
],
页面结构 / 环境
WXML 是构建页面的标签语言,与HTML不同点
- 标签名称不同
- 属性节点不同
- 类似于VUE
WXSS 样式文件,与 CSS 不同点
- 新增了RPX尺寸单位
- 提供全局的样式和局部的样式
- WXSS 仅支持部分CSS选择器
JS 逻辑交互
- app.js 是小程序项目的入口文件,通过App() 函数进行启动小程序
- 页面的js文件,是页面入口文件,通过Page() 函数创建并运行。
- 普通的JS文件,用于封装
宿主环境,是程序运行所必须的依赖环境。
微信提供了那些内容。
- 通信模型
- 运行机制
- 组件
- API
通信模型
分为渲染层(WXSS 和 WXML)和逻辑层(JS)
- 渲染层和逻辑层通信:是由微信客户端进行转发的
- 逻辑层和服务器进行通信:是由客户端进行转发的

运行机制
小程序启动过程
- 把小程序下载到本地
- 解析app.json 全局配置文件
- 执行 app.js 小程序入口文件,调用 APP() 创建小程序实例
- 渲染小程序的首页
- 小程序启动完成
页面渲染的过程
- 加载解析页面的 .json 配置文件
- 加载页面的 .wxml 模板和 .wxss 样式
- 执行页面的 .js 文件,调用 Page() 创建页面实例
- 页面渲染完成
组件
组件分为了 9 大类,分别是:
- 视图容器
- 基础内容
- 表单组件
- 导航组件
- 媒体组件
- map 地图组件
- canvas 画布组件
- 开放能力 9 无障碍访问
视图容器
view
普通视图区域 类似于 HTML 中的 div,是一个块级元素 常用来实现页面的布局效果
scroll-view
可滚动的视图区域 常用来实现滚动列表效果
html
<!-- scroll-y 纵向滚动,x 是横向滚动 -->
<scroll-view id="container1" scroll-y>
<view>A</view>
<view>B</view>
<view>C</view>
</scroll-view>
swiper 和 swiper-item
轮播图容器组件 和 轮播图 item 组件
html
<!-- 轮播图 -->
<swiper>
<swiper-item>
<view style="background-color: red;"></view>
</swiper-item>
<swiper-item>
<view style="background-color: skyblue;"></view>
</swiper-item>
<swiper-item>
<view style="background-color: yellow;"></view>
</swiper-item>
</swiper>
相关参数
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
indicator-dots | boolean | false | 是否显示面板指示点 |
indicator-color | color | rgba(0, 0, 0, .3) | 指示点颜色 |
indicator-active-color | color | #000000 | 当前选中的指示点颜色 |
autoplay | boolean | false | 是否自动切换 |
interval | number | 5000 | 自动切换时间间隔 |
circular | boolean | false | 是否采用衔接滑动 |
常用的基础内容组件
- text 文本组件,行内元素,selectable:支持复制
- rich-text 富文本组件 nodes属性:支持把 HTML 字符串渲染为 WXML 结构
html
<view>
手机号码是:
<text selectable>13633103713</text>
</view>
<rich-text nodes="<h1>标题</h1>"></rich-text>
button
按钮组件 功能比 HTML 中的 button 按钮丰富 通过 open-type 属性可以调用微信提供的各种功能(客服、转发、获取用户授权、获取用户信息等)可以在app.js 中 设置v2还是旧版本的样式
html
<button type="primary">主要</button>
<button type="primary" size="mini">缩小</button>
<button type="primary" size="mini" plain>镂空</button>
image
图片组件 image 组件默认宽度约 300px、高度约 240px
js
<image src="/images/484867b1991bcaf9eb74161c146b719e_720.jpg" mode=""/>
mode 属性用来指定图片的裁剪和缩放模式
mode 值 | 说明 |
---|---|
scaleToFill | (默认值)缩放模式,不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 |
aspectFit | 缩放模式,保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来 |
aspectFill | 缩放模式,保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取 |
widthFix | 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变 |
heightFix | 缩放模式,高度不变,宽度自动变化,保持原图宽高比不变 |
navigator(后面课程会专门讲解)
页面导航组件 类似于 HTML 中的 a 链接
内置API
小程序官方把 API 分为了如下 3 大类:
事件监听 API
- 特点:以 on 开头,用来监听某些事件的触发
- 举例:wx.onWindowResize(function callback) 监听窗口尺寸变化的事件
同步 API
- 特点1:以 Sync 结尾的 API 都是同步 API
- 特点2:同步 API 的执行结果,可以通过函数返回值直接获取,如果执行出错会抛出异常
- 举例:wx.setStorageSync('key', 'value') 向本地存储中写入内容
异步 API
- 特点:类似于 jQuery 中的 $.ajax(options) 函数,需要通过 success、fail、complete 接收调用的结果
- 举例:wx.request() 发起网络数据请求,通过 success 回调函数接收数据
协作成员管理
小程序成员管理体现在管理员对小程序项目成员及体验成员的管理:
- 项目成员:
- 表示参与小程序开发、运营的成员
- 可登录小程序管理后台
管理员可以添加、删除项目成员,并设置项目成员的角色
- 体验成员:
- 表示参与小程序内测体验的成员
- 可使用体验版小程序,但不属于项目成员
管理员及项目成员均可添加、删除体验成员
权限列表
权限 | 运营者 | 开发者 | 数据分析者 |
---|---|---|---|
开发者权限 | √ | ||
体验者权限 | √ | √ | √ |
登录 | √ | √ | √ |
数据分析 | √ | ||
微信支付 | √ | ||
推广 | √ | ||
开发管理 | √ | ||
开发设置 | √ | ||
暂停服务 | √ | ||
解除关联公众号 | √ | ||
腾讯云管理 | √ | ||
小程序插件 | √ | ||
游戏运营管理 | √ |
开发权限
- 开发者权限:可使用小程序开发者工具及对小程序的功能进行代码开发
- 体验者权限:可使用体验版小程序
- 登录权限:可登录小程序管理后台,无需管理员确认
- 开发设置:设置小程序服务器域名、消息推送及扫描普通链接二维码打开小程序
- 腾讯云管理:云开发相关设置
模板与配置
数据绑定
js
// pages/list/index.js
Page({
/**
* 页面的初始数据
*/
data: {
},
})
使用
html
<!-- 直接渲染 -->
<view>{{info}}</view>
<!-- 属性这里也可以直接使用插值表达式 -->
<image src="{{img}}" mode=""/>
三元表达式
html
<view>{{randomNumber1 >= 5 ? '大于5' : '小于5'}}</view>
事件绑定
常用的事件
类型 | 绑定方式 | 事件描述 |
---|---|---|
tap | bindtap 或 bind:tap | 手指触摸后马上离开,类似于 HTML 中的 click 事件 |
input | bindinput 或 bind:input | 文本框的输入事件 |
change | bindchange 或 bind:change | 状态改变时触发 |
当事件回调触发的时候,会收到一个事件对象 event,它的详细属性如下表所示
属性 | 类型 | 说明 |
---|---|---|
type | String | 事件类型 |
timeStamp | Integer | 页面打开到触发事件所经过的毫秒数 |
target | Object | 触发事件的组件的一些属性值集合 |
currentTarget | Object | 当前组件的一些属性值集合 |
detail | Object | 额外的信息 |
touches | Array | 触摸事件,当前停留在屏幕中的触摸点信息的数组 |
changedTouches | Array | 触摸事件,当前变化的触摸点信息的数组 |
target 和 currentTarget 的区别
target 是触发该事件的源头组件,而 currentTarget 则是当前事件所绑定的组件。
e.target 指向的是触发事件的源头组件,因此,e.target 是内部的按钮组件
e.currentTarget 指向的是当前正在触发事件的那个组件,因此,e.currentTarget 是当前的 view 组件
html
<button type="primary" bind:tap="showLog">点击</button>
js
showLog(e) {
console.log(e);
},
想进行data中的count赋值操作
js
showLog(e) {
this.setData({count: this.data.count + 1})
},
参数传递
定义原理是,是前面需要加上,data-变量="值",值可以用插值表达式
html
<button type="primary" bind:tap="showLog" data-count="{{2}}">点击 + 2</button>
js
showLog(e) {
console.log(e.target.dataset.coun);
},
input
html
<input type="text" bindinput="showLog" value="初始值"/>
js
showLog(e) {
console.log(e.detail.value);
},
条件渲染
html
<view wx:if="{{type === 1}}">男</view>
<view wx:elif="{{type === 2}}">女</view>
<view wx:else>人妖</view>
可以用 block 标签,不具备任何效果,只起到包裹作用
用 hidden 也可以实现隐藏,true 隐藏
html
<view hidden="{{type === 1}}">男</view>
wx:if 与 hidden 的对比
运行方式不同
- wx:if 以动态创建和移除元素的方式,控制元素的展示与隐藏
- hidden 以切换样式的方式(display: none/block;),控制元素的显示与隐藏
使用建议
- 频繁切换时,建议使用 hidden
- 控制条件复杂时,建议使用 wx:if 搭配 wx:elif、wx:else 进行展示与隐藏的切换
列表渲染
- 使用 wx:for-index 可以指定当前循环项的索引的变量名
- 使用 wx:for-item 可以指定当前项的变量名
html
<view wx:for="{{arr1}}">
索引是:{{index}},列表:{{item}}
</view>
如何使用 wx:key,注意 key 绑定的是 item.id,也可以使用 index
html
<view wx:for="{{userList}}" wx:key="id">
索引是:{{item.id}},列表:{{item.name}}
</view>
WXSS 模板样式
WXSS 具有 CSS 大部分特性,同时,WXSS 还对 CSS 进行了扩充以及修改,以适应微信小程序的开发。
与 CSS 相比,WXSS 扩展的特性有:
- rpx 尺寸单位
- @import 样式导入
css
@import '/common/common.wxss'
什么是 rpx 尺寸单位
rpx(responsive pixel)是微信小程序独有的,用来解决屏适配的尺寸单位。
rpx 的实现原理非常简单:鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx 把所有设备的屏幕,在宽度上等分为 750 份(即:当前屏幕的总宽度为 750rpx)。
- 在较小的设备上,1rpx 所代表的宽度较小
- 在较大的设备上,1rpx 所代表的宽度较大
小程序在不同设备上运行的时候,会自动把 rpx 的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配。
rpx 与 px 之间的单位换算*
在 iPhone6 上,屏幕宽度为375px,共有 750 个物理像素,等分为 750rpx。则:
- 750rpx = 375px = 750 物理像素
- 1rpx = 0.5px = 1物理像素

官方建议:开发微信小程序时,设计师可以用 iPhone6 作为视觉稿的标准。
开发举例:在 iPhone6 上如果要绘制宽100px,高20px的盒子,换算成rpx单位,宽高分别为 200rpx 和 40rpx。
全局配置
全局配置文件及常用的配置项
小程序根目录下的 app.json 文件是小程序的全局配置文件。常用的配置项如下:
- pages
记录当前小程序所有页面的存放路径
- window
全局设置小程序窗口的外观
- tabBar
设置小程序底部的 tabBar 效果
- style
是否启用新版的组件样式

window
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
navigationBarTitleText | String | 字符串 | 导航栏标题文字内容 |
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色,如 #000000 |
navigationBarTextStyle | String | white | 导航栏标题颜色,仅支持 black / white |
backgroundColor | HexColor | #ffffff | 窗口的背景色 |
backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light |
enablePullDownRefresh | Boolean | false | 是否全局开启下拉刷新 |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为px |
开启全局下拉刷新, enablePullDownRefresh 改成 true
修改下拉刷新的背景色:backgroundColor
上拉触底距离
概念:上拉触底是移动端的专有名词,通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
设置步骤: app.json -> window -> 为 onReachBottomDistance 设置新的数值
注意:默认距离为50px,如果没有特殊需求,建议使用默认值即可。
tabBar
tabBar 是移动端应用常见的页面效果,用于实现多页面的快速切换。小程序中通常将其分为:
- 底部 tabBar
- 顶部 tabBar
注意:
- tabBar中只能配置最少 2 个、最多 5 个 tab 页签
- 当渲染顶部 tabBar 时,不显示 icon,只显示文本
tabBar 的 6 个组成部分
- backgroundColor:tabBar 的背景色
- selectedIconPath:选中时的图片路径
- borderStyle:tabBar 上边框的颜色
- iconPath:未选中时的图片路径
- selectedColor:tab 上的文字选中时的颜色
- color:tab 上文字的默认(未选中)颜色
配置 TabBar
在 app.json 中加入
json
{
"tabBar": {
"list": [ // 列表项
{
"pagePath": "pages/index/index", // 跳转路径
"text": "index" // 内容
},
{
"pagePath": "pages/list/index",
"text": "list"
}
]
},
}
tabBar 节点的配置项
属性 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
position | String | 否 | bottom | tabBar 的位置,仅支持 bottom/top |
borderStyle | String | 否 | black | tabBar 上边框的颜色,仅支持 black/white |
color | HexColor | 否 | tab 上文字的默认(未选中)颜色 | |
selectedColor | HexColor | 否 | tab 上的文字选中时的颜色 | |
backgroundColor | HexColor | 否 | tabBar 的背景色 | |
list | Array | 是 | tab 页签的列表,最少 2 个、最多 5 个 tab |
每个list 如何进行配置呢
属性 | 类型 | 必填 | 描述 |
---|---|---|---|
pagePath | String | 是 | 页面路径,页面必须在 pages 中预先定义 |
text | String | 是 | tab 上显示的文字 |
iconPath | String | 否 | 未选中时的图标路径;当 postion 为 top 时,不显示 icon |
selectedIconPath | String | 否 | 选中时的图标路径;当 postion 为 top 时,不显示 |
网络数据请求
出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
- 只能请求 HTTPS 类型的接口
- 必须将接口的域名添加到信任列表中
登录小程序管理后台


注意事项:
- 域名只支持 https 协议
- 域名不能使用 IP 地址或 localhost
- 域名必须经过 ICP 备案
- 服务器域名一个月内最多可申请 5 次修改
发起请求
js
wx.request({
url: 'https://applet-base-api-t.itheima.net/api/get',
method: 'GET', // post
data: {
name: 'zs',
age: 20
},
success: (res) => {
console.log(res);
}
})
跳过校验 / 跨域 Ajax问题
我们可以在微信开发者工具中,临时开启「开发环境不校验请求域名、TLS 版本及 HTTPS 证书」选项,跳过 request 合法域名的校验。

跨域问题只存在于基于浏览器的 Web 开发中。由于小程序的宿主环境不是浏览器,而是微信客户端,所以小程序中不存在跨域的问题。
Ajax 技术的核心是依赖于浏览器中的 XMLHttpRequest 这个对象,由于小程序的宿主环境是微信客户端,所以小程序中不能叫做"发起 Ajax 请求",而是叫做"发起网络数据请求"。
页面导航
- 在页面上声明一个 <navigator> 导航组件,叫做:声明式导航
- 通过点击 <navigator> 组件实现页面跳转
- 调用小程序的导航 API,实现页面的跳转,叫做:编程式导航
tabBar 页面指的是被配置为 tabBar 的页面。
- url:是路径
- open-type 跳转方式,switchTab 表示 TabBar 页面(必填)
- navigate 表示非TabBar页面
- navigate 是默认值,可以不写 open-type
- navigateBack 表示后退,与 delta 使用,可以实现后退几次,默认值就是1
传递参数
html
<navigator url="/pages/message/index?name=zs&age=17"" open-type="switchTab">跳转消息</navigator>
<navigator open-type="navigateBack" delta="1">后退一步</navigator>
编程导航
API
属性 | 类型 | 是否必选 | 说明 | |
---|---|---|---|---|
url | string | 否 | 需要跳转的页面的路径,路径后不能带参数,返回不需要加 | |
delta | number | 1 | 否 | 当返回时上一层可选,如果值大于页面总数,则首页 |
success | function | 否 | 接口调用成功的回调函数 | |
fail | function | 否 | 接口调用失败的回调函数 | |
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
js
// 跳转到TabBar页面
wx.switchTab({
url: '/pages/message/index?name=zs&age=17"',
})
// 非TabBar页面
wx.navigateTo({
url: '/pages/index22/index?name=zs&age=17"',
})
// 返回上一页
wx.navigateBack({
delta: 1 // 可省略
})
接收参数
js
onLoad(options) {
console.log(options); // 对象里已经包含了
},
下拉刷新 / 上拉触底
用户下拉松开触发
js
onPullDownRefresh() {
this.setData({count: 0})
wx.stopPullDownRefresh() // 处理完成调用停止事件
},
就是移动端,上拉滑动到低了,触发加载更多数据的操作
但是发现有个问题,我们到达一定位置后,频繁滑动同一个距离,也会进行多次触发
js
onReachBottom() {
console.log('触发上拉触底');
},
loading 效果
js
// 触发Loading
wx.showLoading({
title: '数据加载中',
})
// 结束loading
wx.hideLoading()
自定义编译

可以做操作,比如重新编译后进入指定页面

生命周期
生命周期(Life Cycle)是指一个对象从创建 -> 运行 -> 销毁的整个阶段
在小程序中,生命周期分为两类,分别是:
应用生命周期
- 特指小程序从启动 -> 运行 -> 销毁的过程
页面生命周期
- 特指小程序中,每个页面的加载 -> 渲染 -> 销毁的过程

生命周期函数
小程序的应用生命周期函数需要在 app.js 中进行声明,示例代码如下:
js
App({
/**
* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch: function () {
},
/**
* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {
},
/**
* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {
},
/**
* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
*/
onError: function (msg) {
}
})
页面生命周期函数
- onLoad:监听页面加载,只能执行一次
- onReady:监听页面初次渲染完成,只能执行一次
- onUnload:监听页面卸载,只能执行一次
js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
WXS 脚本语言
WXS 结合 WXML 可以构建出页面
wxml 中无法调用在页面的 .js 中定义的函数,但是,wxml 中可以调用 wxs 中定义的函数。因此,小程序中 wxs 的典型应用场景就是"过滤器"。
WXS 和 js 的关系
WXS (Weixin Script) 支持以下数据类型:
- number: 数值类型
- string: 字符串类型
- boolean: 布尔类型
- object: 对象类型
- function: 函数类型
- array: 数组类型
- date: 日期类型
- regexp: 正则表达式类型
WXS 语法特点
不支持的 ES6+ 语法
WXS 不支持以下 ES6 及以上的语法特性:
let
和const
定义变量- 解构赋值
- 展开运算符
- 箭头函数
- 对象属性简写等
支持的 ES5 语法
WXS 支持以下 ES5 语法特性:
- 使用
var
定义变量 - 普通的
function
函数定义方式等
模块系统
WXS 遵循 CommonJS 规范,支持模块化开发:
- module 对象:模块的默认导出
- require() 函数:引入其他模块
- module.exports:导出模块中的功能或对象
内嵌 WXS 脚本
html
<view>{{m1.toUpper('zs')}}</view>
<wxs module="m1">
module.exports.toUpper = function(str) {
return str.toUpperCase()
}
</wxs>
定义外联的 wxs 脚本
wxs 代码还可以编写在以 .wxs 为后缀名的文件内,就像 javascript 代码可以编写在以 .js 为后缀名的文件中一样。示例代码如下:
定义
js
function toUp(str) {
return str.toUpperCase()
}
module.exports = {
toUpper: toUp
}
使用
html
<wxs src="./index.wxs" module="m1"></wxs>
特点
wxs 语言在设计时借大量鉴了 JavaScript 的语法。但是本质上,wxs 和 JavaScript 是完全不同的两种语言!
- 不能作为组件的事件回调
- wxs 不能调用 js 中定义的函数(隔离性)
- wxs 不能调用小程序提供的 API
- 在 iOS 设备上,小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍(性能好)
- 在 android 设备上,二者的运行效率无差异
组件
动态标题
js
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
wx.setNavigationBarTitle({
title: '标题',
position: 'left'
})
},
信息框
js
wx.showToast({
title: '没有更多数据了...',
icon: 'none'
})
自定义组件
- 在项目的根目录中,鼠标右键,创建 components -> test 文件夹
- 在新建的 components -> test 文件夹上,鼠标右键,点击"新建 Component"
- 键入组件的名称之后回车,会自动生成组件对应的 4 个文件,后缀名分别为 .js,.json, .wxml 和 .wxss

引用组件
- 局部引用:组件只能在当前被引用的页面内使用
json
{
"usingComponents": {
"test": "/components/test/test" // 引用页面处
}
}
- 全局引用:组件可以在每个小程序页面中使用
在app.json 中加入
json
{
"usingComponents": {
"test": "/components/test/test" // 引用页面处
}
}
使用
html
<test></test>
区别
注意,在组件的 jSON文件中
json
{
"component": true, // 表示是组件
"usingComponents": {}
}
在 js 中,主函数,不再是page,而是 Component
js
// components/test/test.js
Component({
样式
样式具备隔离性
注意事项:
- app.wxss 中的全局样式对组件无效
- 只有 class 选择器会有样式隔离效果,id 选择器、属性选择器、标签选择器不受样式隔离的影响
建议:在组件和引用组件的页面中建议使用 class 选择器,不要使用 id、属性、标签选择器!
取消样式隔离
方式一:在 js中
js
Component({
options: {
styleIsolation: 'isolated'
},
可选值 | 描述 |
---|---|
isolated | 默认值,启用样式隔离,使用 class 指定的样式将不会相互影响 |
apply-shared | 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面 |
shared | 页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面 |
方式二:在 JSON 中
json
{
"component": true,
"usingComponents": {},
"styleIsolation": "isolated" // 这里控制
}
data 和 mythods
方法中,下划线开头的,是自定义处理方法,没有下划线开头的表示事件处理函数
自定义属性,接收数据
父组件可以传递
js
properties: {
// max: Number 无法使用默认值
max: {
type: Number,
value: 10
}
},
properties 属性和 data 数据的用法相同,它们都是可读可写的
只不过语义上,并不同
由于 data 数据和 properties 属性在本质上没有任何区别,因此 properties 属性的值也可以用于页面渲染,或使用 setData 为 properties 中的属性重新赋值
数据监听器
监听对象,需要对象.属性名,无论该属性被改变还是该对象被重新赋值,都会触发。
如果监听的对象过多,可以使用通配符代替对象.**
,接收的时候,直接写 obj就可以了
在主函数中
js
observers: {
'字段1,字段2': function(字段1新值, 字段2新值) {
},
},
纯数据字段
纯数据字段指的是那些不用于界面渲染的 data 字段。仅仅在当前组件使用的变量
- 好处:纯数据字段有助于提升页面更新的性能。
js
Component({
options: {
// 匹配纯数据字段的正则
pureDataPattern: /^_/
},
组件的生命周期
生命周期函数 | 参数 | 描述说明 |
---|---|---|
created | 在组件实例刚刚被创建时执行 | |
attached | 在组件实例进入页面节点树时执行 | |
ready | 在组件在视图层布局完成后执行 | |
moved | 在组件实例被移动到节点树另一个位置时执行 | |
detached | 在组件实例被从页面节点树移除时执行 | |
error | Object Error | 每当组件方法抛出错误时执行 |
- created 不能调用 setData 函数
- attached 可以用于获取数据等
- detached 组件离开时触发的时候做清理的业务
定义生命周期,在主函数中
js
// 在 lifetimes 中
lifetimes: {
created() {
}
}
页面隐藏、展示、变化的生命周期
生命周期函数 | 描述 |
---|---|
show | 组件所在的页面被展示时执行 |
hide | 组件所在的页面被隐藏时执行 |
resize | 组件所在的页面尺寸变化时执行,携带参数 Object Size |
js
Component({
pageLifetimes: {
hide() {},
show() {},
resize() {}
}
})
插槽
组件里放 slot 标签后,可以在使用处,中直接放内容,默认会转到slot上
启用多个插槽
js
Component({
options: {
multipleSlots: true // 启用
},
给插槽定义名字
html
<slot name="kk"></slot>
使用
html
<test>
<view slot="kk">222</view>
</test>
组件传参
父传子
html
<!-- 父 -->
<test count="{{count}}"></test>
<!-- 子接收 -->
properties: {
count: {
type: Number,
value: 0
}
},
子传父
bind:自定义触发点="父组件中触发的方法"
html
<test count="{{count}}" bind:sync="syncCount"></test>
obj.detail 是传递过来的对象
js
// 在父组件中
syncCount(obj) {
console.log('sync', , obj.detail);
},
子组件,触发方法,并传递参数
js
this.triggerEvent('sync', {value: this.data.count})
获取子组件实例
可以根据 class 和 id 选择器
js
const sa = this.selectComponent('.symc')
behaviors 共享
用于实现组件间代码共享的特性,类似于 Vue.js 中的 "mixins"
每个 behavior 可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。
每个组件可以引用多个 behavior,behavior 也可以引用其它 behavior。
创建 js 文件并导出
js
module.exports = Behavior({
properties: {},
data: {
username: 'zs'
},
methods: {
}
})
使用,只能应用于组件
js
const myBeh = require('../../behavior/myBeh')
Component({
behaviors: [myBeh],
同名覆盖情况
如果是属性名同名,当前组件的权重大于引用的组件
behavior 中所有可用的节点

NPM 第三方
npm 包有如下 3 个限制:
- 不支持依赖于 Node.js 内置库的包
- 不支持依赖于浏览器内置对象的包
- 不支持依赖于 C++ 插件的包
Vant Weapp 是有赞前端团队开源的一套小程序 UI 组件库,助力开发者快速搭建小程序应用。
首先先对项目进行 npm 初始化 npm init -y

安装 npm i @vant/weapp -S --production

启用 npm 支持

关闭样式
将 app.json 中的 "style": "v2" 去除,小程序的新版基础组件强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱。
使用
在app.json或index.json中引入组件
json
"usingComponents": {
"van-button": "@vant/weapp/button/index"
}
html
<van-button type="default">默认按钮</van-button>
全局样式
在 html 中创建,具备作用域,在 html 中最好
css
html {
--main-color: #d42525; // 定义,使用 var 使用
}
.box1, .box2 {
background-color: var(--main-color);
}
在 app.wxss 中,写入 CSS 变量,即可对全局生效:
这样定制,为什么是 Page 节点呢,因为小程序的节点就是 Page节点
wxss
page {
--button-danger-background-color: #C00000;
--button-danger-border-color: #D60000;
}
Vant-Wapp 变量名地址
Promise 化
安装
js
npm i miniprogram-api-promise -S
在 app.js 文件中
js
// 导入
import {
promisifyAll
} from 'miniprogram-api-promise'
const wxp = wx.p = {}
// pomise 化
promisifyAll(wx, wxp)
js
async getSwiperList() {
const aa = await wx.p.request({
url: 'https://applet-base-api-t.itheima.net/slides',
method: 'GET',
})
console.log(aa);
},
全局数据共享
使用 mobx-miniprogram 配合 mobx-miniprogram-bindings 实现全局数据共享
- mobx-miniprogram 用来创建 Store 实例对象
- mobx-miniprogram-bindings 用来把 Store 中的共享数据或方法,绑定到组件或页面中使用
我这里安装的
json
"mobx-miniprogram": "^6.12.3"
"mobx-miniprogram-bindings": "^5.0.0"
定义仓库
js
import {
observable, action
} from 'mobx-miniprogram'
export const store = observable({
num1: 1,
num2: 2,
// 计算属性
get sum() {
return this.num1 + this.num2
},
// 异步函数,必须使用 function,不能使用箭头函数,否则找不到this
updateNum1: action(function (step) {
this.num1 += step
})
})
使用仓库
js
import {
createStoreBindings
} from 'mobx-miniprogram-bindings'
import {
store
} from '../../store/store'
Page({
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.storeBindings = createStoreBindings(this, {
store, // 使用仓库
fields: ['num1', 'sum', 'num2'], // 映射字段
actions: ['updateNum1'] // 映射函数
})
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
this.storeBindings.destroyStoreBindings() // 需要卸载
},
在组件中使用 Store
js
import {
storeBindingsBehavior
} from 'mobx-miniprogram-bindings'
import {
store
} from '../../store/store'
Component({
behaviors: [storeBindingsBehavior],
storeBindings: {
// 数据源
store,
// 映射字段
fields: {
num1: 'num1', // 字符串中是stroe中的字段
num2: 'num2',
sum: 'sum'
},
// 映射异步方法
actions: {
updateNum1: 'updateNum1'
}
},
分包
分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
对小程序进行分包的好处主要有以下两点:
- 可以优化小程序首次启动的下载时间
- 在多团队共同开发时可以更好的解耦协作
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
分包后,小程序项目由 1 个主包 + 多个分包组成:
- 主包:一般只包含项目的启动页面或 TabBar 页面、以及所有分包都需要用到的一些公共资源
- 分包:只包含和当前分包有关的页面和私有资源
分包前

分包后

分包的加载规则 / 分包的体积限制
在小程序启动时,默认会下载主包并启动主包内页面
- tabBar 页面需要放到主包中 当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示
- 非 tabBar 页面可以按照功能的不同,划分为不同的分包之后,进行按需下载
目前,小程序分包的大小有以下两个限制:
- 整个小程序所有分包大小不超过 16M(主包 + 所有分包)
- 单个分包/主包大小不能超过 2M
配置分包 / 打包原则
在 app.json 中,定义下面,会自动创建分包
json
{
// 配置分包
"subPackages": [
{ // 第一个分包,根节点是PkgA,pages配置页面
"root": "PkgA",
"name": "p1", // 起别名
"pages": [
"pages/cat/cat"
]
}
],
查看项目大小

打包原则
- 小程序会按 subpackages 的配置进行分包,subpackages 之外的目录将被打包到主包中
- 主包也可以有自己的 pages(即最外层的 pages 字段)
- tabBar 页面必须在主包内
- 分包之间不能互相嵌套
引用原则
- 主包无法引用分包内的私有资源
- 分包之间不能相互引用私有资源
- 分包可以引用主包内的公共资源
独立分包
独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行。
最主要的区别:是否依赖于主包才能运行
- 普通分包必须依赖于主包才能运行
- 独立分包可以在不下载主包的情况下,独立运行
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。
原因如下:当小程序从普通的分包页面启动时,需要首先下载主包 而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
注意:一个小程序中可以有多个独立分包。
json
"subPackages": [
{
"root": "PkgA",
"pages": [
"pages/cat/cat"
],
"independent": true // 标志为独立分包
}
],
独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源!
- 主包无法引用独立分包内的私有资源
- 独立分包之间,不能相互引用私有资源
- 独立分包和普通分包之间,不能相互引用私有资源
- 特别注意:独立分包中不能引用主包内的公共资源
分包预下载
指在什么时候触发分包的下载
在 app.json 中,使用 preloadRule 节点定义分包的预下载规则
json
"preloadRule": {
"pages/concat/index": { // 访问的路径
"packages": ["PkgA"], // 触发后加载包
"network": "all" // 在什么情况下加载,all全部,wifi
}
},
限制
小程序中,所有的分包预下载限制是2M,如果多个判断所有分包体积大于2M,无法进行分包预下载。


自定义 TabBar
自定义 tabBar 分为 3 大步骤,分别是:
- 配置信息
json
"tabBar": {
"custom": true, // 自定义tabBar,true
"list": []
}
- 创建目录代码,根目录,创建 custom-tab-bar 和 index文件


引用 Tabbar 标签
- 编写 tabBar 代码
list 节点要保留,是为了兼容低版本。并设置 custom 为 true
注意需要覆盖样式时,需要配置一下作用域
js
Component({
options: {
styleIsolation: 'shared'
},