数据绑定
001 - 如何定义页面的数据
- 小程序每个页面,是由 4 部分组成,其中
.js
文件内可以定义页面的数据、生命周期函数、其他业务逻辑 - 如果要在
.js
文件内定义页面的数据,只需把数据定义在data
节点下即可
002 - Mustache
语法格式
把
data
中的数据绑定到页面中渲染,使用Mustache
语法(双大括号) 将变量包裹起来即可
<view>{{ info }}</view>
Mustache
语法的主要场景- 绑定内容
- 绑定属性
- 运算(三元表达式、算术运算、逻辑判断、字符串运算、数据路径运算)
003 - 案例代码
<!-- 页面结构 -->
<!-- 绑定内容和属性 -->
<view id="item-{{id}}">{{ info }}</view>
<!-- 算数运算 -->
<view>{{ 1 + 1 }}</view>
<!-- 三元表达式 -->
<view>{{ id == 10 ? "正确" : "错误" }}</view>
// 页面数据
Page({
data: {
info: 'i miss you',
id: 10,
arr: [1, 2, 3]
}
})
bindtap
绑定触摸事件
001 - data
和 文本框之间的数据同步
- 在文本框的
input
事件处理函数中,通过事件参数event
,能够访问到文本框的最新值- 语法结构
event.detail.value
- 语法结构
- 通过
this.setData(dataObject)
方法,可以把页面中的data
数据重新赋值
案例代码
<!-- 页面结构 -->
<button bindtap='handle' type='warn'>我是按钮</button>
<input bindinput='inputHandle' value='输入框'></input>
<input bindinput='datasync' value='{{ msg }}'></input>
// 页面逻辑
Page({
data: {
msg: ''
},
handle: function (event) {
console.log('按钮绑定的事件')
console.log(event)
},
inputHandle: function (e) {
console.log(e)
},
// 数据同步演示
datasync: function (e) {
console.log(e.detail.value)
this.setData({
msg: e.detail.value
})
}
// coding...
})
小程序中的事件传参
001 - 不能再绑定事件的同时传递参数
- 小程序的事件传参比较特殊,不能在为组件绑定事件的同时,为事件处理函数传递参数
- 小程序会把
bindtap
后指定的值,统一当做事件名称来处理
// 错误做法
<button bindtap='eventHandle(123)' type='primary' data-info='info'>传递参数</button>
002 - 通过 data-*
自定义属性传参
- 如果要在组件触发事件处理函数的时候,传递参数,可以为组件提供
data-*
自定义属性传参
003 - 获取 data-*
自定义属性中传递的参数
- 通过事件参数
event-target-dataset.参数名
,能够获取data-*
自定义属性传递到事件处理函数中的参数
004 - 案例代码
<!-- 页面结构 -->
<button bindtap='eventHandle' type='primary' data-info='info'>传递参数</button>
// 页面逻辑
Page({
data: {},
eventHandle: function (e) {
console.log(e.target.dataset.info)
}
// coding...
})
wxs
基础语法
001 - 使用 module.exports
向外共享成员
- 通过 module.exports 属性,可以对外共享本模块的私有变量与函数
var foo = “‘hello world’ from wxs”; // 定义私有变量 foo
var bar = function (d) { // 定义私有函数 bar
return d
}
// 通过 modules.exports 向外共享私有成员
module.exports = {
FOO: foo, // 向外共享私有变量 foo
bar: ba, // 向外共享私有函数 bar
};
// module.exports 中挂载 msg 变量
module.exports.msg = “some msg”
002 - 使用 require
引入其它 wxs
模块 以及注意事项
- 在
wxs
模块中引用其他wxs
文件模块,可以使用 require 函数。
// 使用 require 导入 tools.wxs 脚本
var tools = require("./tools.wxs")
// 得到的 tools 对象,可以直接访问到 tools.wxs 中向外暴露的变量和方法
console.log(tools)
注意事项 :
- 只能引用
wxs
文件模块,且必须使用相对路径 wxs
模块均为单例wxs
模块在第一次被引用时,会自动初始化为单例对象。- 多个页面,多个地方,多次引用,使用的都是同一个
wxs
模块对象。
- 如果一个
wxs
模块在定义之后,一直没有被引用,则该模块不会被解析与运行。
、内嵌 wxs
脚本
001 - 使用规则
wxs
代码可以编写在wxml
文件中的<wxs></wxs>
标签内,就像javascript
代码可以编写在html
文件中的<script></script>
标签内一样。wxml
文件中的每个<wxs></wxs>
标签,必须提供一个module
属性,用来指定当前<wxs></wxs>
标签的模块名。在单个wxml
文件内,建议其值唯一。- module 属性值的命名必须符合下面两个规则:
- 首字符必须是:字母(a-z A-Z),下划线(_)
- 剩余字符可以是:字母(a-z A-Z),下划线(_), 数字(0-9)
002 - 案例代码
<view>{{ info.msg }}</view>
<wxs module='info'>
var msg = '我在等风来'
module.exports = {
msg: msg
}
</wxs>
二十五、外联 wxs
脚本文件
001 - 使用规则
wxs
代码可以编写在以.wxs
为后缀名的文件内,就像 javascript
代码可以编写在以.js
为后缀名文件中一样。- 在
wxml
中如果要引入外联的wxs
脚本,必须为<wxs></wxs>
标签添加module
和src
属性。module
用来为<wxs></wxs>
标签指定模块名,作为当前页面访问这个模块的标识名称;src
用来指定当前<wxs></wxs>
标签要引入的脚本路径,必须是相对路径;
002 - 案例代码
// .wxs 文件
var msg = '风铃响,故人归'
var handle = function (params) {
return params
}
module.exports = {
msg: msg,
handle: handle
}
<wxs src='./ling.wxs' module='feng'></wxs>
<view>{{ feng.msg }}</view>
<view>{{ feng.handle('我在等风') }}</view>
注意:在 wxs
中不要使用高级的JS
语法
001 - wx:if
<view wx:if='{{id < 10}}'>JavaScript</view>
<view wx:elif='{{id == 10}}'>HTML</view>
<view wx:else='{{id > 10}}'>CSS</view>
002 - block wx:if
- 因为
wx:if
是一个控制属性,需要将它添加到一个标签上。 - 如果要一次性判断多个组件标签,可以使用一个
<block></block>
标签将多个组件包装起来,并在上边使用wx:if
控制属性。 <block/>
并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。
<block wx:if='{{ id == 10 }}'>
<view>JavaScript</view>
<view>HTML</view>
<view>CSS</view>
</block>
003 - hidden
- 使用
hidden="{{condition}}"
也能控制元素的显示与隐藏
<view hidden='{{ id > 10 }}'>前端三板斧</view>
wx:if
的区别
004 - hidden 和 - 被
wx:if
控制的区域,框架有一个局部渲染的过程,会根据控制条件的改变,动态创建或销毁对应的UI
结构。 wx:if
是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。- 相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
- 总结:
wx:if
有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则wx:if
较好。
二、列表渲染
001 - wx:for
- 在组件上使用
wx:for
控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。 - 默认数组的当前项的下标变量名默认为
index
,数组当前项的变量名默认为item
。
<view wx:for='{{ arr }}' wx:key='index'>
我是{{ item }} -- 索引是 {{ index }}
</view>
002 - block wx:for
wx:for
可以用在<block></block>
标签上,以渲染一个包含多节点的结构块。
<block wx:for='{{ arr }}' wx:key='index'>
<view>值:{{item}} -- 索引{{index}}</view>
</block>
003 - 指定索引和当前项的变量名
- 使用
wx:for-item
可以指定数组当前元素的变量名 - 使用
wx:for-index
可以指定数组当前下标的变量名,
<view wx:for='{{ arr }}' wx:for-item='foritem' wx:for-index='forindex' wx:key='index'>
我是{{ foritem }} -- 索引是 {{ forindex }}
</view>
004 - 列表渲染中的 wx:key
-
wx:key
的作用说明-
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如
<input/>
中的输入内容,<checkbox/>
的选中状态),需要使用wx:key
来指定列表中项目的唯一的标识符。 -
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
-
-
wx:key
的注意事项key
值必须具有唯一性,且不能动态改变key
的值必须是数字或字符串- 保留关键字
*this
代表在for
循环中的item
本身,它也可以充当key
值,但是有以下限制:需要item
本身是一个唯一的字符串或者数字。 - 如不提供
wx:key
,会报一个warning
, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
三、下拉刷新
001 - 下拉刷新的概念以及场景
- 概念:下拉刷新是移动端更新列表数据的交互行为,用户通过手指在屏幕上自上而下的滑动,可以触发页面的下拉刷新,更新列表数据。
- 应用场景:在移动端,数据列表是常见的页面效果,更新列表数据是最基本的页面需求,相比于按钮刷新、定时刷新来说,下拉刷新的用户体验方便友好,已经成为移动端刷新列表数据的最佳解决方案。
002 - 如何启动下拉刷新
- 在
app.json
的window
选项中或页面配置中开启enablePullDownRefresh
。 - 可以通过
wx.startPullDownRefresh()
触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
注意: 一般情况下,推荐在页面配置中为需要的页面单独开启下拉刷新行为
003 - 设置下拉刷新窗口的样式
- 在
app.json
的window
选项中或页面配置中修改backgroundColor
和backgroundTextStyle
选项。 backgroundColor
用来配置下拉刷新窗口的背景颜色,仅支持16进制颜色值backgroundTextStyle
用来配置下拉刷新loading
的样式,仅支持dark
和light
004 - 监听下拉刷新事件
需要先开启下拉刷新
- 为页面添加
onPullDownRefresh()
函数,可以监听用户在当前页面的下拉刷新事件。
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
console.log('触发下拉刷新啦')
}
005 - 停止下拉刷新
- 处理完下拉刷新后,下拉刷新的 loading 效果会一直显示,不会主动消失,
- 因此需要手动隐藏下拉刷新的 loading 效果,调用
wx.stopPullDownRefresh()
可以停止当前页面的下拉刷新。
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
console.log('触发下拉刷新啦')
wx.stopPullDownRefresh()
}
四、 上拉加载
001 - 上拉加载的概念以及场景
- 概念:在移动端,随着手指不断向上滑动,当内容将要到达屏幕底部的时候,页面会随之不断的加载后续内容,直到没有新内容为止,我们称之为上拉加载更多。上拉加载更多的本质就是数据的分页加载。
- 应用场景:在移动端,列表数据的分页加载,首选的实现方式就是上拉加载更多。
002 - 设置上拉加载的距离
- 在
app.json
的window
选项中或页面配置中设置触底距离onReachBottomDistance
。单位为px
,默认触底距离为50px
。 - 为页面添加
onReachBottom()
函数,可以监听用户在当前页面的上拉触底事件,从而实现上拉加载更多列表数据的效果。
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
console.log('触发上拉刷新啦')
},
五、 其他事件
001 - 页面滑动事件onPageScroll
- 监听用户滑动页面事件
- 得到
scrollTop
,页面在垂直方向已滚动的距离(单位px
)
- 得到
onPageScroll: function (e) {
console.log(e)
}
002 - 分享事件 onShareAppMessage
- 监听用户点击页面内转发按钮(
<button> 组件 open-type="share"
) - 右上角菜单“转发”按钮的行为,并自定义转发内容。
参数 | 类型 | 说明 |
---|---|---|
from | String | 转发事件来源。button:页面内转发按钮;menu:右上角转发菜单 |
target | Object | 如果 from 值是 button,则 target 是触发这次转发事件的 button,否则为 undefined |
webViewUrl | String | 页面中包含组件时,返回当前的url |
- 自定义转发内容, return 一个 Object 就可以
字段 | 说明 | 默认值 |
---|---|---|
title | 转发标题 | 当前小程序名称 |
path | 转发路径 | 当前页面 path ,必须是以 / 开头的完整路径 |
imageUrl | 自定义图片路径,可以是本地文件路径、代码包文件路径或者网络图片路径。支持PNG 及JPG 。显示图片长宽比是 5:4。 | 使用默认截图 |
Page({
onShareAppMessage: function (res) {
if (res.from === 'button') {
// 来自页面内转发按钮
console.log(res.target)
}
return {
title: '自定义转发标题',
path: '/page/user?id=123',
imageUrl: ''
}
}
})
003 - 点击 tab 时触发事件 onTabItemTap
参数 | 类型 | 说明 |
---|---|---|
index | String | 被点击 tabItem 的序号,从0开始 |
pagePath | String | 被点击tabItem 的页面路径 |
text | String | 被点击 tabItem 的按钮文字 |
onTabItemTap(item) {
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
}
六、小程序导航 – 声明式导航
001 - 导航到非 tabBar
页面
非
tabBar
页面指的是没有被当作tabBar
进行切换的页面。
- 案例代码:
<navigator url="/pages/about/about">跳转到 about 页面</navigator>
- 注意事项
url
属性设置需要跳转的路径- 页面路径应该以 / 开头,
- 路径必须提前在
app.json
的pages
节点下声明
002 - 导航到 tabBar
页面
navigator组件单纯使用
url
属性,无法导航到tabBar
页面,必须需要结合open-type
属性进行导航。
- 案例代码
<navigator url="/pages/person/person" open-type="switchTab">跳转到 tabBar 页面</navigator>
003 - 后退导航
小程序如果要后退到上一页面或多级页面,需要把
open-type
设置为navigateBack
,同时使用delta
属性指定后退的层数
- 案例代码
<navigator open-type='navigateBack' delta='1'> 返回上一页 </navigator>
<navigator open-type='navigateBack' delta='2'> 返回上上一页 </navigator>
七、小程序导航 – 编程式导航
001 - 导航到非 tabBar
页面
通过
wx.navigateTo(Object object)
方法,可以跳转到应用内的某个页面。但是不能跳到
tabbar
页面。
- 参数文档
- 代码案例
// 跳转到非导航页面
handle: function () {
wx.navigateTo({
url: '/pages/about/about',
success: function () {
console.log('Hello about')
}
})
},
002 - 导航到 tabBar
页面
通过
wx.switchTab(Object object)
方法,可以跳转到tabBar
页面,并关闭其他所有非
tabBar
页面
- 参数文档
- 案例代码
// 跳转到 tabBar 页面
tabBarHandle: function () {
wx.switchTab({
url: '/pages/person/person',
success: function() {
console.log('Hello Person')
}
})
}
003 - 后退导航
通过
wx.navigateBack(Object object)
方法,关闭当前页面,返回上一页面或多级页面。
- 参数文档
- 案例代码
handle: function () {
wx.navigateBack({
delta: 1
})
},
twoHandle: function () {
wx.navigateBack({
delta: 2
})
},
八、小程序导航 – 导航传参
001 - 声明式导航传参
navigator
组件的url
属性用来指定导航到的页面路径,同时路径后面还可以携带参数,参数与路径之间使用?
分隔,参数键与参数值用=
相连,不同参数用&
分隔。
- 案例代码
<navigator url="/pages/about/about?age=18&name=shuji">跳转到 about 页面</navigator>
002 - 编程式导航传参
wx.navigateTo(Object object)
方法的objec
t 参数中,url
属性用来指定需要跳转的应用内非tabBar
的页面的路径, 路径后可以带参数。参数与路径之间使用?
分隔,参数键与参数值用=
相连,不同参数用&
分隔。
- 案例代码
// 跳转到 tabBar 页面
tabBarHandle: function () {
wx.switchTab({
url: '/pages/person/person?age=18&name=shuji',
success: function() {
console.log('Hello Person')
}
})
},
003 - 接受传递的参数
不论是声明式导航还是编程式导航,最终导航到的页面可以在
onLoad
生命周期函数中接收传递过来的参数。
- 案例代码
onLoad: function (options) {
// 打印传递出来的参数
console.log(options)
},
004 - 导航栏自定义编译模式快速传参
- 小程序每次修改代码并编译后,会默认从首页进入,但是在开发阶段,我们经常会针对特定的页面进行开发,为了方便编译后直接进入对应的页面,可以配置自定义编译模式,步骤如下:
- 单击工具栏上的“普通编译”下拉菜单
- 单击下拉菜单中的“添加编译模式”选项
- 在弹出的“自定义编译条件窗口”,按需添加模式名称、启用页面、启动参数、进入场景等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PzBbH4IE-1617870965097)(./images/4chuanc1.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t2Al0pl0-1617870965099)(./images/4chuanc2.png)]
九、网络数据请求
001 - 小程序后台配置
- 每个微信小程序需要事先设置一个通讯域名,小程序只可以跟指定的域名进行网络通信。
- 服务器域名请在 「小程序后台-开发-开发设置-服务器域名」 中进行配置,配置时需要注意:
- 域名只支持
https
(request
、uploadFile
、downloadFile
) 和wss
(connectSocket
) 协议 - 域名不能使用
IP
地址或localhost
- 域名必须经过
ICP
备案 - 服务器域名一个月内可申请5次修改
- 域名只支持
注意: 网络配置详情
002 - 跳过域名校验
- 在微信开发者工具中,可以临时开启 「开发环境不校验请求域名、TLS 版本及 HTTPS 证书」 选项,跳过服务器域名的校验。此时,在微信开发者工具中及手机开启调试模式时,不会进行服务器域名的校验。
注意:在服务器域名配置成功后,建议开发者关闭此选项进行开发,并在各平台下进行测试,以确认服务器域名配置正确。
注意: 网络配置详情
003 - 小程序发送 get 与 Post 请求
小程序发送请求使用
wx.request()
方法,
- Get 案例代码
getData: function () {
wx.request({
url: 'xxxx',
method: 'get',
success: function (res) {
console.log(res)
}
})
},
- Post 代码案例
postData: function () {
wx.request({
url: 'https://www.liulongbin.top:8082/api/post',
method: 'post',
data: {
name: 'shuji'
},
success: function (res) {
console.log(res)
}
})
},
注意: method 如果不进行配置,默认参数是 get 请求方式
004 - 小程序中没有跨域限制
- 在普通网站开发中,由于浏览器的同源策略限制,存在数据的跨域请求问题,从而衍生出了 JSONP 和 CORS 两种主流的跨域问题解决方案。
- 注意:小程序的内部运行机制与网页不同,小程序中的代码并不运行在浏览器中,因此小程序开发中,不存在数据的跨域请求限制问题
小程序基础 第四天
一、小程序组件 – 创建与引用
001 - 组件的创建
- 在项目的根目录中,鼠标右键,创建 components 文件夹 --> test
- 在新建的 components -> test 文件夹上,鼠标右键,点击“新建 Component”
- 为新建的组件命名之后,会自动生成组件对应的 4 个文件,后缀名分别为
.js
,.json
,.wxml
和.wxss
注意:应当尽量将不同的组件,存放到单独的文件夹中,从而保证清晰的目录结构
002 - 组件的引用
- 在需要引用组件的页面中,找到页面的
.json
配置文件,新增usingComponents
节点 - 在
usingComponents
中,通过键值对的形式,注册组件;键为注册的组件名称,值为组件的相对路径 - 在页面的
.wxml
文件中,把注册的组件名称,以标签形式在页面上使用,即可把组件展示到页面上
{
"usingComponents": {
"first-com": "../../component/com01/com01"
}
}
注册组件名称时,建议把组件名称使用中横线进行连接,例如 vant-button 或 custom-button
二、小程序组件 – 组件的样式
- 组件对应
wxss
文件的样式,只对组件wxml
内的节点生效。编写组件样式时,需要注意以下几点: - 组件和引用组件的页面不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用
class
选择器。 - 组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。
- 子元素选择器(.a>.b),只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
- 继承样式,如
font
、color
,会从组件外继承到组件内。 - 除继承样式外,
app.wxss
中的样式、组件所在页面的样式对自定义组件无效。
注意:以上语法不推荐死记硬背,建议使用 class 选择器
三、小程序组件 – 数据与方法
001 - 使用 data 定义组件的私有数据
-
小程序组件中的
data
与小程序页面中的data
用法一致,区别是:- 页面的
data
定义在Page()
函数中 - 组件的
data
定义在Component()
函数中
- 页面的
-
在组件的
.js
文件中:- 如果要访问
data
中的数据,直接使用this.data.数据名称
即可 - 如果要为
data
中的数据重新赋值,调用this.setData({ 数据名称: 新值 })
即可
- 如果要访问
-
在组件的 .wxml 文件中
- 如果要渲染 data 中的数据,直接使用 {{ 数据名称 }} 即可
002 - 使用 methods 定义组件的事件处理函数
- 和页面不同,组件的事件处理函数,必须定义在 methods 节点中
methods: {
handle: function () {
console.log('组件的方法要定义在 methods 中')
this.setData({
num: this.data.num + 1
})
console.log(this.data.num)
}
}
四、小程序组件 – properties
001 - properties 简介
组件的对外属性,用来接收外界传递到组件中的数据。 类似于
Vue
中的props
-
组件的
properties
和data
的用法类似,它们都是可读可写的,只不过:data
更倾向于存储组件的私有数据properties
更倾向于存储外界传递到组件中的数据
002 - properties 语法结构
properties: {
a: { // 属性名
type: String, // 属性的数据类型
value: '' // 默认值
},
a: String
}
注意:type 的可选值为 Number,String、Boolean、Object、Array、null(表示不限制类型)
003 - 向组件传递 properties 的值
使用数据绑定的形式,向子组件的属性传递动态数据
<second-com prop-price="{{ priceData }}"></second-com>
注意:
- 在定义 properties 时,属性名采用驼峰写法(propertyName);
- 在 wxml 中,指定属性值时,则对应使用连字符写法(property-name=“attr value”),
- 应用于数据绑定时,采用驼峰写法(attr="{{propertyName}}")。
004 - 案例代码
-
外界通过在组件的标签上,以属性的形式进行传递
<my-prop money="{{money}}"></my-prop>
-
组件内部通过properties进行接收,并且可以限定类型
properties: { money: { // 属性名 type: Number, // 属性的数据类型 value: 0 // 默认值 }, money: Number // 简化的定义方式 }
注意:
- type 的可选值为 Number,String、Boolean、Object、Array、null(表示不限制类型)
005 - 组件内修改 properties
properties 的值是可读可写的,可以通过
setData
修改properties
中任何属性的值,
- 案例代码
methods: {
handle: function () {
this.setData({
propPrice: this.properties.propPrice + 1
})
console.log(this.properties.propPrice)
}
}
五、小程序组件 – 数据监听器
001 - 基本使用方法
数据监听器可以用于监听和响应任何属性和数据字段的变化,从而执行特定的操作
observers: {
'propPrice, num': function (newPropPrice, newNum) {
console.log(newPropPrice)
console.log(newNum)
}
},
002 - 监听子数据字段语法
- 案例代码
// 监控某个子数据的代码
Component({
observers: {
'some.subfield': function (subfield) {
// 使用 setData 设置 this.data.some.subfield 时触发
// (除此以外,使用 setData 设置 this.data.some 也会触发)
},
'arr[12]': function (arr12) {
// 使用 setData 设置 this.data.arr[12] 时触发
// (除此以外,使用 setData 设置 this.data.arr 也会触发)
}
}
})
// 使用通配符 ** 监听所有子数据字段的变化
Component({
observers: {
'some.field.**': function (field) {
// 使用 setData 设置 this.data.some.field 本身或其下任何子数据字段时触发
// (除此以外,使用 setData 设置 this.data.some 也会触发)
field === this.data.some.field
}
}
})
六、组件的生命周期
组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。
- 最重要的生命周期是
created
,attached
,detached
,包含一个组件实例生命流程的最主要时间点。- 组件实例刚刚被创建好时,
created
生命周期被触发。此时还不能调用setData
。 通常情况下,这个生命周期只应该用于给组件 this 添加一些自定义属性字段。 - 在组件完全初始化完毕、进入页面节点树后,
attached
生命周期被触发。此时,this.data
已被初始化完毕。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。 - 在组件离开页面节点树后,
detached
生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则detached
会被触发。
- 组件实例刚刚被创建好时,
其他: 组件生命周期详解
七、小程序插槽的使用
001 - 默认插槽
在组件的
wxml
中可以包含slot
节点,用于承载组件使用者提供的wxml
结构。
-
默认情况下,一个组件的
wxml
中只能有一个slot
。需要使用多slot
时,可以在组件js
中声明启用。 -
注意:小程序中目前只有默认插槽和多个插槽,暂不支持作用域插槽。
-
案例代码
// 组件模板
<view>
<view>我是组件</view>
<slot></slot>
</view>
// 引用组件的页面模板
<second-com>
<view>你好,我是引用组件</view>
</second-com>
002 - 多个插槽
- 在组件中,需要使用多
slot
时,可以在组件js
中声明启用。- 案例代码
Component({
options: {
multipleSlots: true
}
})
- 在组件的 wxml 中使用多个 slot 标签,以不同的 name 来区分不同的插槽
- 案例代码
// 引用组件的页面模板
<cmpnt-slot>
<view slot="header">这是页面头部的插槽</view>
<view slot="footer">这是页面底部的插槽</view>
</cmpnt-slot>
- 使用多个插槽
// 组件插槽
<slot name="header"></slot>
<view>
这是页面的主题内容
</view>
<view>
这是页面的主题内容
</view>
<view>
这是页面的主题内容
</view>
<slot name="footer"></slot>
八、 组件间的通信
001 - 组件之间的三种基本通信方式
WXML
数据绑定:用于父组件向子组件的指定属性传递数据,仅能设置JSON
兼容数据- 事件:用于子组件向父组件传递数据,可以传递任意数据。
- 父组件通过
this.selectComponent
方法获取子组件实例对象,便可以直接访问组件的任意数据和方法。
002 - this.selectComponent
使用
父组件的
.js
文件中,可以调用this.selectComponent(string)
函数并指定id
或class
选择器, 获取子组件对象调用 ,可以返回指定组件的实例对象
- 案例代码
// 使用组件的页面模板
<second-com class="second" id="second" prop-price="{{ priceData }}">
<view slot="name">你好,这是 name 插槽 </view>
<view slot="age">你好,这是 age 插槽</view>
</second-com>
// 使用组件的 .js 文件,使用方法触发
changeData: function () {
// console.log(this.selectComponent('#second'))
console.log(this.selectComponent('.second'))
},
- 注意事项
- 不能传递标签选择器(component-a),不然返回的是
null
- 不能传递标签选择器(component-a),不然返回的是
003 - 通过事件监听实现子向父传值
事件系统是组件间通信的主要方式之一。自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。
- 案例代码
事件系统是组件间通信的主要方式之一。
- 子组件通过triggerEvent触发事件
- 父组件通过定义自定义事件的事件函数来接收子组件传递过来的值
案例
准备工作
-
父组件定义一个数据接受值
data: { parentMoney:0 }
<view>我是父亲,已破产:{{parentMoney}}</view>
-
子组件定义一个按钮,当点击按钮的时候给父组件传值
data: { money: 10000000 }
<view> 我是儿子,我有钱:{{money}} <button bindtap="sendMoney">给父亲拨款</button> </view>
实现传值步骤
-
在子组件内部定义sendData事件函数,并且通过triggerEvent给父组件传值
sendMoney () { // 触发一个自定义事件(事件需要在使用组件的标签上),并且发送一个数据 this.triggerEvent('myEvent',{ money:this.data.money }) }
-
因为要触发myEvent这个事件,所以在使用组件的位置,绑定自定义事件
<my-event bind:myEvent="getMoney"></my-event>
-
在父组件定义getData事件函数,并且通过事件对象获取传递过来的数据
getMoney (e) { console.log(e.detail.money) this.setData({ parentMoney: e.detail.money }) }