小程序开发者账号的注册
- Appid: wx7c1a7c8cc78fac72
- AppSecret:xxx
小程序代码的项目结构
1.项目的基本组成结构
- pages目录:用来存放所有小程序的界面
- pages数组中的第一项就是小程序项目的首页
- utils目录:用来存放工具性质的模块,例如格式化时间的模块
- app.js:小程序项目的入口文件
- app.json:小程序项目的全局配置文件
- 配置项pages:记录当前小程序所有页面的路径。可以在此增加路径,保存编译后就会新建小程序页面
- 配置项window:全局定义小程序所有界面的背景色、文字颜色等。
- style:全局定义小程序组件所使用的样式版本
- sitemapLocation:用来指明sitemap.json的位置
- app.wxss:小程序项目的全局样式文件
- project.config.json:项目的配置文件
- setting 中保存了编译相关的配置
- projectname 中保存的是项目名称
- appid 中保存的是小程序的账号ID
- sitemap.json:用来配置小程序及其页面是否允许被微信索引
- 关闭siteMap的索引提示:在project.config.json 的 setting 中配置字段checkSiteMap为false
2.小程序页面的组成部分
- .js文件:页面的脚本文件,存放页面的数据、事件处理函数等
- .json文件:当前页面的配置文件,配置窗口的外观、表现等
- .wxss文件:当前页面的样式文件
- .wxml文件:页面的模板结构文件
3.小程序代码的主要构成
- WXML:全称为WeiXin Markup Language,类似于网页开发中的HTML。它和HTML的主要区别是:
- 标签名称不同:例如HTML中的div标签,在WXML中提供了与之类似的view标签。
- 属性节点不同:例如HTML中a标签使用href作为属性表示链接地址,而在WXML中与a标签对应的navigator标签使用url作为属性。
- WXML提供了类似于Vue的模板语法:例如数据绑定、列表渲染、条件渲染。
- WXSS:全称为Wei Xin Style Sheets,类似于网页开发中的CSS。它与CSS的区别:
- 提供了rpx尺寸单位
- 提供了全局的样式和局部样式
- WXSS 仅支持部分 CSS 选择器
- 小程序中的js文件:分为三类
小程序中组件的分类
1.常用的视图容器类组件
- view:普通视图区域,类似于HTML中的div元素,是一个块级元素,常用来实现页面的布局效果
- 示例:实现横向布局效果,使用flex布局
<!--wxml文件--> <view class="container1"> <view>A</view> <view>B</view> <view>C</view> </view> <!--wxss文件--> .container1 view{ width: 100px; height: 100px; line-height: 100px; text-align: center; } .container1 view:nth-child(1) { background-color: red; } .container1 view:nth-child(2) { background-color: green; } .container1 view:nth-child(3) { background-color: blue; } .container1 { display: flex; justify-content: space-between; }
- scroll-view:可滚动的视图区域,常用来实现滚动列表效果
- 示例:实现纵向滚动效果
<!-- scroll-x属性表示允许横向滚动 --> <!-- scroll-y属性表示允许纵向滚动 --> <!-- 使用纵向滚动,必须给scroll-view一个固定高度 --> <scroll-view class="container1" scroll-y="true"> <view>A</view> <view>B</view> <view>C</view> </scroll-view> .container1 { height: 100px; border: 1px solid red; } .container1 view { width: 100px; height: 100px; line-height: 100px; text-align: center; } .container1 view:nth-child(1) { background-color: red; } .container1 view:nth-child(2) { background-color: green; } .container1 view:nth-child(3) { background-color: blue; }
- swiper 和 swiper-item:轮播图容器组件,可以用来做轮播图
-
swipper组件的常用属性如下
-
示例:实现轮播效果
<swiper class="swiper-container" indicator-dots="true" autoplay="true" indicator-color="red" indicator-active-color="white" interval="1000" circular="true"> <swiper-item>A</swiper-item> <swiper-item>B</swiper-item> <swiper-item>C</swiper-item> </swiper> .swiper-container { width: 100%; height: 100px; } .swiper-container swiper-item { line-height: 100px; text-align: center; background-color: chartreuse; }
-
2.常用的基础内容组件
-
text:文本组件,类似于HTML中的span标签,是一个行内元素。
- 示例:通过该组件的selectable属性实现长按选中文本内容的效果
<text user-select="true">这段文字长按可以选中</text>
-
rich-text:富文本组件,支持把HTML字符串渲染为 WXML 结构
- 示例:通过rich-text组件的nodes属性节点,把 HTML 字符串渲染为对应的 UI 结构
<rich-text nodes="<h1 style='color:red;'>test</h1>"></rich-text>
3.其他常用组件
-
button:按钮组件
- type属性:指定按钮的类型
- size属性:指定按钮的尺寸
- plain属性:按钮是否镂空,背景色透明。
-
image:图片组件,image组件默认宽度约300px、高度约 240px
- mode 属性用来指定图片的裁剪和缩放模式,常用的 mode 属性值如下:
- mode 属性用来指定图片的裁剪和缩放模式,常用的 mode 属性值如下:
-
navigator组件:页面导航组件,类似于HTML中的a元素
WXML模板语法
1.数据绑定
- 在页面配置文件中的data配置项中定义数据
- 在WXML模板文件中使用数据:使用插值语法。在微信小程序开发中,插值语法既可以绑定内容,也可以绑定属性。不同于vue,vue中通过v-bind指令或者v-model指令绑定属性。
- 示例:
<!--wxml文件-->
<view>
<!-- 使用插值语法绑定内容 -->
<text>{{msg}}</text>
<!-- 绑定内容时也可以进行三元运算、算术运算等 -->
<text>{{count + 100}}</text>
<!-- 使用插值语法绑定属性 -->
<image src="{{src}}" mode="widthFix"></image>
</view>
<!--页面配置文件中-->
/**
* 页面的初始数据
*/
data: {
msg: 'helloworld',
src: '/images/link-01.png',
count: 0
},
2.事件绑定
-
小程序中常用到的事件如下:
-
当事件被触发,回调函数执行的时候,会收到一个事件对象event,该对象的详细属性如下所示:
target和currentTarget属性的区别:target 是触发该事件的源头组件,而 currentTarget 则是当前事件所绑定的组件。
3. 事件绑定:
1. 通过绑定tap事件响应用户的触摸行为,在事件回调函数中为data中的数据进行赋值
```
data: {
count: 0
},
// e为事件对象
btnTapHandler(e) {
this.setData({
count: this.data.count + 1
})
}
```
2. 通过绑定input事件来响应文本框的输入事件
```
<input bindinput="inputHandler"></input>
inputHandler(e) {
// e.detail.value为文本输入框中变化后的新值
console.log(e.detail.value)
}
```
- 在事件处理函数中为data中的数据赋值:通过调用
this.setData(dataObject)
方法,可以给页面data中的数据重新赋值 - 事件传参:可以为组件提供
data-xxx
自定义属性进行传参,其中xxx代表的是参数的名字。- 参数的获取:
事件对象.target.dataset.参数名
- 参数的获取:
<!-- 事件传参示例:info即为参数的名字 -->
<button bindtap="btnTapHandler" data-info="{{2}}" type="primary">事件传参</button>
// e为事件对象
btnTapHandler(e) {
// 获取向时间回调函数中传递的参数的值
console.log(e.target.dataset.info)
}
- 实现文本框和data之间的数据同步:因为不存在vue中数据的双向绑定特性,所在在微信小程序中的实现主要是在事件回调函数中通过通过调用this.setData(dataObject)方法,给页面data中的数据重新赋值
<input bindinput="inputHandler" value="{{count}}"></input>
inputHandler(e) {
this.setData({
count: e.detail.value
})
}
3.条件渲染
- 在小程序中使用
wx:if
和wx:elif
、wx:else
来判断是否渲染一个组件。
<view>
<view wx:if="{{type === 1}}">男</view>
<view wx:elif="{{type === 2}}">女</view>
<view wx:else="{{type === 3}}">保密</view>
</view>
- 一次控制多个组件的展示与隐藏,可以使用一个
block
标签将多个组件包裹起来,在block标签上使用wx:if
属性。block标签类似于vue中的template标签,并不是一个组件,它只是一个包裹性质的容器,不会在页面中做任何渲染。
<block wx:if="{{type === 0}}">
<view>AAA</view>
<view>BBB</view>
<view>CCC</view>
</block>
<block wx:else="{{type === 1}}">
<view>DDD</view>
</block>
- hidden属性:可以控制元素的显示和隐藏。
<view hidden="{{type === 0}}">AAA</view>
- wx:if和hidden的比较:wx:if等同于vue中的v-if指令,它通过动态创建和移除元素的方式,控制元素的展示与隐藏;hidden等同于vue中的v-show指令,该属性控制元素的display属性控制元素的显示和隐藏。
- 元素频繁切换,考虑到效率,应当使用hidden
- 控制条件复杂,应当搭配使用wx:elif、wx:else控制元素的显示和隐藏。
4.列表渲染
- 使用wx:for可以进行列表渲染,循环中每一项的索引使用index表示,循环中的每一个当前项使用item表示。
<view wx:for="{{list}}">
<text>索引为:{{index}},姓名为:{{item.name}}</text>
</view>
data: {
list: [
{name: '张三', age: 23},
{name: '李四', age: 25},
{name: '王五', age: 26}
]
}
- 指定表示索引的变量名和循环中的每一个当前项的变量名:使用 wx:for-index可以指定当前循环项的索引的变量名,使用wx:for-item可以指定当前项的变量名
<!--指定表示索引的变量名称为idx,表示当前项的变量名为itm-->
<view wx:for="{{list}}" wx:for-index="idx" wx:for-item="itm">
<text>索引为:{{idx}}, 姓名为:{{itm.name}}</text>
</view>
- 为渲染出来的列表项指定唯一的key值可以使用
wx:key
值。
<view wx:for="{{list}}" wx:key="id">
<text>索引为:{{index}},姓名为:{{item.name}}</text>
</view>
data: {
list: [
{id: 1, name: '张三', age: 23},
{id: 2, name: '李四', age: 25},
{id: 3, name: '王五', age: 26}
]
},
WXSS模板样式
1.简介
- 简介:WXSS:全称为Wei Xin Style Sheets,类似于网页开发中的css.
2.WXSS中扩展的特性:
- rpx尺寸单位:rpx全称为responsive pixel,是微信小程序独有的,用来解决屏幕适配的尺寸单位。为了实现屏幕的自动适配,rpx把所有设备的屏幕,在宽度上等分为750份(即:当前屏幕的总宽度为 750rpx)
- 在 iPhone6上,屏幕宽度为375px,共有750个物理像素,等分为 750rpx。所以1个rpx等于0.5个px,1个px等于2个rpx。官方建议:开发微信小程序时,设计师可以用 iPhone6 作为视觉稿的标准
- @import进行外联样式的导入
<!--common文件夹位于项目根目录下-->
@import "/common/common.wxss";
3.全局样式和局部样式
- 全局样式:app.wxss文件中定义的是全局样式,作用于每一个页面。
- 局部样式:在pages目录下每一个页面的wxss文件中定义的是局部样式,只能作用于当前页面。
全局配置与页面配置
1.全局配置
-
小程序项目根目录下的app.json是小程序的全局配置文件。常用的配置项包括pages、window、tabBar、style、
-
小程序窗口的组成部分如下图所示:
-
window节点的常用配置项如下:
-
tabBar节点主要用于实现多页面的快速切换,在小程序中通常将其分为底部tabBar和顶部tabBar。
-
tabBar中只能配置最少 2 个、最多5个tab页签
-
当渲染顶部tabBar时,不显示icon,只显示文本
-
tabBar的六个组成部分如下:
-
tabBar节点的配置项如下所示:
-
每个list配置项的配置选项如下所示:
-
2.页面配置
- 每一个页面都有自己的json文件作为页面的配置文件。
- 页面配置中常用的配置项:
发送网络请求
1.小程序中网络数据请求的限制
- 出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
- 只能请求 HTTPS 类型的接口
- 在小程序管理后台配置 request 合法域名
- 后端程序员仅仅提供了http协议的接口、暂时没有提供 https 协议的接口。可以在微信开发者工具中点击详情=》本地设置=》勾选不校验合法域名来跳过request合法域名的校验。
2.发送网络请求
- 发送get请求:
wx.request({
url: 'https://www.escook.cn/api/get',
method: 'GET',
data: {
name: '李四',
age: 23
},
// 响应成功执行的回调
success: (res) => {
console.log(res)
}
})
- 发送post请求:
wx.request({
url: 'https://www.escook.cn/api/post',
method: 'POST',
data: {
name: '李四',
age: 23
},
success: (res) => {
console.log(res)
}
})
页面导航
页面导航:页面之间的相互跳转
1.小程序中实现页面导航的两种方式
-
声明式导航:在页面上声明一个navigator导航组件,通过点击navigator组件实现页面跳转。
- 导航到tabBar页面(即app.json中tabBar配置项中配置的页面):使用navigator组件跳转到指定的tabBar页面,同时指定url属性和open-type属性。url属性表示要跳转的页面地址,必须以/开头,open-type表示跳转的方式,必须为switchTab
<!--从home首页跳转到消息页--> <navigator open-type="switchTab" url="/pages/message/message">导航到消息页</navigator>
- 导航到非tabBar页面:使用navigator组件跳转到普通的非tabBar页面,同时指定url属性和open-type属性。url属性表示要跳转的页面地址,必须以/开头,open-type表示跳转的方式,必须为navigate
<!--从首页导航到非tabBar页info--> <navigator url="/pages/info/info" open-type="navigate">导航到非tabBar页面</navigator> <!--open-type="navigate"可以省略--> <navigator url="/pages/info/info">导航到非tabBar页面</navigator>
- 后退导航:可以指定open-type属性和delta属性,后退到上一页面或者多级页面。open-type 的值必须是navigateBack,表示要进行后退导航,delta 的值必须是数字,表示要后退的层级。如果只是后退到上一页面,则可以省略delta属性,因为其默认值就是1
<navigator open-type="navigateBack" delta="1">返回上一页</navigator>
-
编程式导航:调用小程序的API,实现页面的跳转。
- 导航到tabBar页面:调用
wx.switchTab(Object object)
方法,可以跳转到 tabBar页面。其中 Object 参数对象的属性列表如下:
<button type="primary" bindtap="goToMessage">导航到tabBar页面</button> <!--home.js--> goToMessage() { wx.switchTab({ url: '/pages/message/message', }) }
- 导航到非tabBar页面:调用
wx.navigateTo(Object object)
方法,可以跳转到非tabBar的页面。其中 Object 参数对象的属性列表如下:
<button type="primary" bindtap="goToInfo">跳转到info页面</button> goToInfo() { wx.navigateTo({ url: '/pages/info/info', }) }
- 后退导航:调用
wx.navigateBack(Object object)
方法,可以返回上一页面或多级页面。其中 Object 参数对象可选的属性列表如下:
<button type="warn" bindtap="goToBack">返回到上一页</button> goToBack() { wx.navigateBack({ delta: 1 }) }
- 导航到tabBar页面:调用
2.导航传参
- 声明式导航传参:navigator组件的url属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数。其中参数与路径之间使用问好分隔,参数键与参数值之间使用等号相连,不同参数键值对使用&分隔。
<navigator url="/pages/info/info?name=zs&age=24">导航到非tabBar页面</navigator>
- 编程式导航传参:调用
wx.navigateTo(Object object)
方法跳转页面时,也可以携带参数
<button type="default" bindtap="goToInfo">跳转到info页面</button>
goToInfo() {
wx.navigateTo({
url: '/pages/info/info?id=3&age=25',
})
}
- 在页面的生命周期函数onload中接收导航参数(不管编程式导航还是声明式导航)。
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// options就是导航传递过来的参数对象
console.log(options)
}
页面事件
1.下拉刷新事件
- 下拉刷新:指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。
- 启用下拉刷新的方式:
- 全局开启下拉刷新:在app.json的window节点中,将 enablePullDownRefresh 设置为 true
- 局部开启下拉刷新:在页面的.json配置文件中,将 enablePullDownRefresh 设置为 true。这个方式推荐使用,因为并不是所有的页面需要开启下拉刷新的效果。
- 设置下拉刷新窗口的样式:
- backgroundColor:设置下拉刷新窗口的背景颜色,仅支持16 进制的颜色值
- backgroundTextStyle:设置下拉刷新 loading 的样式,仅支持 dark 和 light
- 监听页面的下拉刷事件:在页面的.js文件中,通过 onPullDownRefresh()函数即可监听当前页面的下拉刷新事件
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.setData({
count: 0
})
},
- 停止下拉刷新的效果:下拉刷新的loading效果会一直显示,不会主动消失,所以需要手动隐藏下拉刷新的 loading 效果。调用
wx.stopPullDownRefresh()
可以停止当前页面的下拉刷新。
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.setData({
count: 0
})
// 当数据重置成功后,关闭下拉刷新的效果
wx.stopPullDownRefresh()
},
2.上拉触底事件
- 上拉触底:通过手指在屏幕上的上拉滑动操作,从而加载更多数据的行为。
- 监听页面的上拉触底事件:在页面的.js文件中,通过 onReachBottom()函数即可监听当前页面的上拉触底事件。
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
console.log("触发了页面触底事件!")
},
- 配置上拉触底距离:上拉触底距离指的是触发上拉触底事件时,滚动条距离页面底部的距离。页面的.json 配置文件中,通过
onReachBottomDistance
属性来配置上拉触底的距离。小程序默认的触底距离是 50px - 上拉触底添加loading提示效果:
wx.showLoading({title: '数据加载中...'})
- 隐藏loading提示效果:
wx.hideLoading()
生命周期
1.生命周期的分类
- 在小程序中,生命周期分为两类:
- 页面的生命周期:指的是小程序中每个页面的加载=》渲染=》销毁的过程。
- 应用的生命周期:指的是小程序从启动=》运行=》销毁的过程。
2.生命周期函数
- 应用的生命周期函数:特指小程序从启动 -> 运行 -> 销毁期间依次调用的那些函数
App({
/**
* 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
*/
onLaunch: function () {
console.log("小程序初始化完成!")
},
/**
* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {
console.log("小程序从后台进入前台!")
},
/**
* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {
console.log("小程序从前台进入后台!")
},
/**
* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
*/
onError: function (msg) {
}
})
- 页面的生命周期函数:特指小程序中,每个页面从加载 -> 渲染 -> 销毁期间依次调用的那些函数
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {},
/**
* 生命周期函数--监听页面显示
*/
onShow() {},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {},
WXS脚本
1.WXS脚本概述
- WXS:全称Wei Xin Script,是小程序独有的一套脚本语言,结合WXML使用。
- 应用场景:wxml中无法调用在页面的.js中定义的函数,但是,wxml中可以调用wxs中定义的函数。因此,小程序中 wxs 的典型应用场景就是“过滤器”。
- WXS和JS的关系:
- WXS中的数据类型:
- number:数值类型
- string:字符串类型
- boolean:布尔类型
- object:对象类型
- function:函数类型
- array:数组类型
- date:日期类型
- regexp:正则
- WXS不支持类似于ES6及以上的语法格式:不支持:let、const、解构赋值、展开运算符、箭头函数、对象属性简写等;支持var定义变量,普通function函数等类似于ES5的语法。
- WXS遵循CommonJS规范:比如module 对象、require函数、module.exports对象
- WXS中的数据类型:
2.WXS脚本的基础语法
- 内嵌WXS脚本:WXS代码可以编写在WXML文件中的
wxs
标签内,等同于在HTML文件中将js代码编写在script标签内。- wxs标签必须提供module属性,用于指定当前wxs的模块名称,方便再WXML中访问模块中的成员。
<!--name为data中定义的属性--> <view>姓名为:{{moduleA.toUpper(name)}}</view> <wxs module="moduleA"> module.exports.toUpper = function(str) { return str.toUpperCase() } </wxs>
- WXML中使用外联的WXS脚本:wxs代码可以编写在以wxs为后缀名的文件中,等同于将js代码编写在以js为后缀名的文件中。
- 定义外联脚本:在utils目录下新建tools.wxs文件
function toLower(str) { return str.toLowerCase() } module.exports = { toLower: toLower }
- 在WXML中使用外联脚本:使用wxs标签引入外联脚本,使用module属性指定模块的名称,src属性指定要引入的脚本的路径,必须是相对路径。
<text>姓名为:{{moduleA.toLower(name)}}</text> <!-- 引用外联的wxs脚本,并命名为moduleA --> <wxs module="moduleA" src="../../utils/tools.wxs"></wxs>
3.WXS的特点
- 和js这门脚本语言是不一样的
- WXS编写的代码不能作为组件中的事件回调,它的应用场景是作为过滤器, 例如
<!--对data中的name数据进行过滤,转小写-->
<text>姓名为:{{moduleA.toLower(name)}}</text>
- 隔离性:隔离性指的是wxs的运行环境和其他JavaScript代码是隔离的
- wxs 不能调用 js 中定义的函数
- wxs 不能调用小程序提供的 API
- 性能好:
- 在 iOS设备上,小程序内的WXS会比JavaScript 代码快 2 ~ 20 倍
- 在 android 设备上,二者的运行效率无差异
自定义组件
1.组件的创建与引用
- 组件的创建:
- 在项目的根目录下新建components文件夹,用于存放组件
- 为了将不同的组件存放在不同的目录,在components目录下新建一个文件夹用于存放组件,例如
test
- 在test目录下右击新建组件,键入组件名称后回车,即会生成四个文件。
- 组件的引用方式:
- 局部引用:组件只能在当前被引用的页面内使用。引用方式:在页面的json配置文件中定义如下:
// home页面的json配置文件下 { "usingComponents": { "my-test1": "/components/test/test1" } } //home页面中使用组件 <my-test1></my-test1>
- 全局引用:组件可以在每个小程序页面中使用。引用方式:在全局配置文件app.json下进行配置,如下所示:
{ // 和pages节点平级 "usingComponents": { "my-test2": "/components/test2/test2" }, } // 使用组件 <my-test2></my-test2>
- 引用方式的选择:如果某组件在多个页面中经常被用到,建议进行“全局引用”;如果某组件只在特定的页面中被用到,建议进行“局部引用”
- 组件和页面的区别:
- 组件和页面都由js、json、wxss、wxml、四个文件组成。
- 组件的.json文件中需要声明"component":true 属性
- 组件的 .js 文件中调用的是Component()函数,而页面调用的是Page函数
- 组件的事件处理函数需要定义到methods节点中,而页面是定义在与data平级的地方
2.样式
- 组件的样式隔离:
- 默认情况下,自定义组件的样式只对当前组件生效,不会影响到组件之外的UI结构。即组件A的样式不会影响组件B的样式,组件A的样式也不会影响小程序页面的样式,小程序页面的样式(包括app.wxss中定义的样式)也不会影响组件A的样式。
- 只有class选择器会有样式隔离效果,id选择器、属性选择器、标签选择器不受样式隔离的影响。因此建议在组件和引用组件的页面中建议使用class选择器,不要使用 id、属性、标签选择器!
- 修改组件的样式隔离选项:默认情况下,自定义组件的样式隔离特性能够防止组件内外样式互相干扰的问题。但有时,我们希望在外界能够控制组件内部的样式,此时,可以通过styleIsolation修改组件的样式隔离选项
-
styleIsolation的可选值如下:
-
示例:
// 在组件的js文件下新增如下配置 options: { // 启动样式隔离 // styleIsolation: 'isolated' // styleIsolation: 'apply-shared' styleIsolation: 'shared' },
-
3.自定义组件的数据、方法、属性
- data数据:在小程序的组件中,用于组件模板渲染的私有数据,需要定义到 data 节点中
- 方法:在小程序的组件中,事件处理函数和自定义方法需要定义到methods节点中。自定义方法建议以下划线_开头,方便自定义组件中对纯数据字段进行处理。
- properties属性:在小程序的组件中,properties属性用来接收外界传递到组件中的数据
// 在组件的js文件下
/**
* 组件的属性列表
*/
properties: {
count: {
type: Number,// 属性值的数据类型
value: 10 // 属性的默认值为10
}
// 简写形式
count: Number
},
// 外界使用到组件的页面进行传值
<my-test1 count="100"></my-test1>
- data和properties的区别:两者指向同一块地址,是一个东西。只不过data更倾向于存储组件的私有数据,properties 更倾向于存储外界传递到组件中的数据。
- properties属性值的修改:在vue中修改properties属性的值会产生警告,但是在微信小程序中,properties和data就是同一个东西,所以properties属性的值也可以用于页面渲染,或使用setData为properties中的属性重新赋值
addCount() {
this.setData({
count: this.properties.count + 100
})
}
4.数据监听器
- 数据监听器:用于监听和响应任何属性和数据字段的变化,从而执行特定的操作。它的作用类似于vue中的 watch 侦听器。在小程序组件中,数据监听器的基本语法格式如下:
// 监听单个或者多个字段
Component({
observers: {
'字段1, 字段2': function(字段1的新值, 字段2的新值) {
}
},
})
// 监听对象中的单个或者多个属性
Component({
observers: {
'对象.属性A, 对象.属性B': function(属性A的新值, 属性B的新值) {
}
},
})
// 通配符 ** 表示监听对象中所有属性的变化
Component({
observers: {
'对象.**': function(obj) {
}
},
})
- 示例:
/**
* 组件的初始数据
*/
data: {
x1: 0,
x2: 0,
sum: 0,
user: {
name: 'zs',
age: 23
}
},
observers: {
'x1, x2': function(x1, x2) {
this.setData({
sum: x1 + x2
})
},
'user.name, user.age': function(name, age) {
}
},
5.纯数据字段
- 纯数据字段:纯数据字段指的是那些不用于界面渲染的data字段。
- 应用场景:例如有些情况下,某些data中的字段既不会展示在界面上,也不会传递给其他组件,仅仅在当前组件内部使用。带有这种特性的data字段适合被设置为纯数据字段。
- 作用:纯数据字段有助于提升页面更新的性能。
- 使用规则:在Component构造器的options节点中,指定 pureDataPattern为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段。示例如下:
data: {
// 纯数据字段
_count: 100,
}
Component({
// 在组件的js文件下新增如下配置
options: {
// 指定所有以_开头的数据字段为纯数据字段
pureDataPattern: /^_/
},
}
6.组件的生命周期
-
小程序组件可用的全部生命周期函数如下:
- lifetimes节点:在小程序组件中,生命周期函数可以直接定义在Component构造器的第一级参数中,可以在lifetimes字段内进行声明,例如:
Component({ lifetimes: { attached() { }, detached() { } }, }
-
组件所在页面的生命周期:有时,自定义组件的行为依赖于页面状态的变化,此时就需要用到组件所在页面的生命周期。例如,监听着组件所在的页面展示,页面显示时,执行某个动作。
- 在自定义组件中,组件所在页面的生命周期函数有如下 3 个,分别是:
- show:组件所在的页面被展示时执行
- hide:组件所在的页面被隐藏时执行
- resize:组件所在的页面尺寸变化时执行
- pageLifetimes节点:组件所在页面的生命周期函数,需要定义在pageLifetimes节点中,例如:
Component({ pageLifetimes: { show: function() { console.log("show") }, hide: function() { console.log("hide") }, resize: function() { console.log("resize") } }, }
- 在自定义组件中,组件所在页面的生命周期函数有如下 3 个,分别是:
7.插槽
- 插槽:在自定义组件的wxml结构中,可以提供一个
节点(插槽),用于承载组件使用者提供的 wxml 结构。在封装组件时,在wxml文件中使用slot作为占位符,在使用组件时为slot占位符提供具体的内容节点。 - 单个插槽:在小程序中,默认每个自定义组件中只允许使用一个
进行占位,这种个数上的限制叫做单个插槽。
<!--组件的封装者-->
<view>这是组件的内部节点</view>
<!-- 使用slot进行占位,具体的内容由组件的使用者决定 -->
<slot></slot>
<!--组件的使用者-->
<my-test1 count="100">
<!-- 下面的内容将放在组件slot的位置上 -->
<view>AAA</view>
<view>BBB</view>
</my-test1>
- 多个插槽:
- 启用多个插槽:在小程序的自定义组件中,需要使用多
插槽时,可以在组件的.js文件中,通过如下方式进行启用:
Component({ // 在组件的js文件下新增如下配置 options: { multipleSlots: true //在组件定义时的选项中启用多slot支持 } }
- 组件中定义多个插槽:可以在组件的.wxml中使用多个
<slot>
标签,以不同的name来区分不同的插槽。
<!-- name为first的第一个插槽 --> <slot name="first"></slot> <!-- name为second的第二个插槽 --> <slot name="second"></slot>
- 使用多个插槽:在使用带有多个插槽的自定义组件时,需要用slot属性来将节点插入到不同的
中。
<my-test1 count="100"> <view slot="first">AAA</view> <view slot="second">BBB</view> </my-test1>
- 启用多个插槽:在小程序的自定义组件中,需要使用多
8.父子组件之间的通信
- 父子组件之间通信的三种方式:
- 属性绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容的数据
<!--父组件中--> /** * 组件的初始数据 */ data: { count: 100 } <!--父组件向子组件传递值--> <my-test3 count="{{count}}">父组件向子组件传值</my-test3> <!--子组件使用properties接收--> Component({ /** * 组件的属性列表 */ properties: { count: Number } }
- 事件绑定:用于子组件向父组件传递数据,可以传递任意数据
- 在父组件的js中,定义一个函数(即事件的回调函数),这个函数即将通过自定义事件的形式,传递给子组件
methods: { // 在父组件的 js 中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件。 synCount(e) { // e即事件对象 console.log(e) this.setData({ count: e.detail.value }) } }
- 在父组件的wxml中,通过自定义事件的形式,将步骤1中定义的函数引用,传递给子组件
<!-- 使用bind:自定义事件名称 --> <my-test3 count="{{count}}" bind:sync="synCount">父组件向子组件传值</my-test3>
- 在子组件的js中,通过调用
this.triggerEvent('自定义事件名称', { /* 参数对象 */ })
,将数据发送到父组件。子组件触发负组件中定义的事件名称
methods: { addCount() { this.setData({ count: this.properties.count + 100 }) this.triggerEvent('sync', { value: this.properties.count }) } }
- 在父组件的js中,在事件回调函数内通过e.detail获取到子组件传递过来的数据
synCount(e) { // e即事件对象 console.log(e) this.setData({ count: e.detail.value }) }
- 获取组件实例:父组件还可以通过
this.selectComponent("id或者类选择器")
获取子组件实例对象,这样就可以直接访问子组件的任意数据和方法。
<!-- 使用bind:自定义事件名称 --> <my-test3 count="{{count}}" bind:sync="synCount" class="class1" id="id1">父组件向子组件传值</my-test3> <button type="warn" bindtap="getChild">获取子组件实例</button> getChild() { const child = this.selectComponent('.class1') // 调用子组件的setData方法 child.setData({ count: this.properties.count + 1 }) }
9.自定义组件的behaviors
- behaviors:behaviors是小程序中,用于实现组件间代码共享的特性,类似于 Vue.js 中的 “mixins”。每个behavior可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。每个组件可以引用多个behavior,behavior 也可以引用其它 behavior。
- behavior的创建:调用
Behavior(Object object)
方法即可创建一个共享的behavior实例对象,供所有的组件使用
// 项目根目录下新建behaviors文件夹,该文件夹下新建xxx.js
module.exports = Behavior({
properties: {
},
data: {
name: 'test'
},
methods: {
}
})
- behavior的导入和使用
// 导入自定义的behavior模块
const myBehavior = require("../../behavior/my-behavior")
Component({
// 将导入的behavior实例对象挂载到behaviors数组节点中
behaviors: [myBehavior]
})
// 可以在页面上直接使用behavior模块中定义的数据
- behaviors中可用的节点
Vant Weapp的基本使用
1.安装
- 小程序中支持使用npm安装一些第三方包,从而来提高小程序的开发效率。
- Vant Weapp的安装:参考Vant Weapp官网
- 在项目根目录下执行
npm init
进行初始化 - 通过npm安装
npm i vant-weapp -S --production
- 在微信开发者工具中构建npm包
- 全局引入或者局部引入Vant Weapp中的组件。全局引入示例如下
{ "usingComponents": { "my-test2": "/components/test2/test2", "van-button": "./miniprogram_npm/vant-weapp/button/index" } }
- 在项目根目录下执行
2.全局主题样式的定制
- CSS变量:也叫做自定义属性。
- CSS变量的定义:变量名需要以两个减号开始。例如:
<!--定义一个CSS变量,其作用域为整个HTML文档--> html { --main-bg-color: brown; }
- CSS变量的使用:使用var函数取值
.class1 { background-color: var(--main-bg-color); }
- ant Weapp 使用CSS变量来实现定制主题。在app.wxss 中,写入 CSS 变量,即可对全局生效。例如:
/* 指定作用域为page,page为页面的根元素 */
page {
--button-primary-background-color: #2b4b6b;
--button-primary-border-color: #ff0000;
}
API promise化
- API promise化:指的是通过额外的配置,将官方提供的、基于回调函数的异步API,升级改造为基于Promise 的异步 API,从而提高代码的可读性、维护性,避免回调地狱的问题。
- API promise化的实现:
- 安装
miniprogram-api-promise
包。每次安装新的包后,先删除miniprogram_npm目录,然后需要在微信开发者工具中重新构建npm包
npm install --save miniprogram-api-promise@1.0.4
- 在小程序入口文件app.js中调用promisifyAll()方法
import {promisifyAll} from 'miniprogram-api-promise' const wxp = wx.p = {} // promisify all wx对象的API promisifyAll(wx, wxp)
- 安装
- 调用promise化后的异步API示例:
<van-button type="primary" bindtap="getInfo">按钮</van-button>
async getInfo() {
const {data: result} = await wx.p.request({
url: 'https://www.escook.cn/api/get',
method: 'GET',
data: {
name: 'zs',
age: 23
}
})
console.log(result)
},
全局数据共享
- 全局数据共享也叫做状态管理,是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有:Vuex、Redux、MobX 等。
1.小程序中的全局数据共享方案
- 在小程序中,可使用
mobx-miniprogram
配合mobx-miniprogram-bindings
实现全局数据共享。其中:
mobx-miniprogram用来创建Store实例对象。mobx-miniprogram-bindings用来把Store中的共享数据或方法,绑定到组件或页面中使用。 - MobX相关包的安装:
npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
分包
1.简介
- 分包:分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
- 分包的好处:
- 可以优化小程序首次启动的下载时间
- 在多团队共同开发时可以更好的解耦协作
- 分包的加载规则:
- 在小程序启动时,默认会下载主包并启动主包内页面。进入小程序都会首先看到tabBar页面,因此tabBar 页面需要放到主包中
- 当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示,非 tabBar 页面可以按照功能的不同,划分为不同的分包之后,进行按需下载。这样就不用将小程序的所有页面和资源都打包到一起,节省小程序首次启动时间。
2.分包的使用
- 在app.json的subpackages节点中声明分包的结构。小程序会按subpackages的配置进行分包,subpackages 之外的目录将被打包到主包中
3.独立分包
- 独立分包:独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行。
- 独立分包和普通分包的区别:是否依赖于主包运行
- 普通分包必须依赖于主包才能运行
- 独立分包可以在不下载主包的情况下,独立运行
- 独立分包的应用场景:开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下:
- 当小程序从普通的分包页面启动时,需要首先下载主包,而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度。注意:一个小程序中可以有多个独立分包。
- 独立分包的配置方法:通过independent声明独立分包
- 分包预下载:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
- 预下载分包的行为,会在进入指定的页面时触发。在app.json中,使用preloadRule节点定义分包的预下载规则