很多情况下,组件内展示的内容(数据、样式、标签),并不是在组件内写死的,而且可以由使用者来决定。
向组件传递数据:
大部分情况下,组件只负责布局和样式,内容是由使用组件的对象决定的;
所以,我们经常需要从外部传递数据给我们的组件,让我们的组件来进行展示;
如何传递呢?
使用properties属性;
支持的类型:
String、 Number、 Boolean
Object、 Array、 null(表示不限制类型)
默认值:
可以通过value设置默认值;
示例代码
<section-info title="我是标题" content="我是内容: 哈哈哈哈" />
Component({
// 在组件中接收数据
properties: {
title: {
type: String,
value: "我是默认标题"
},
content: {
type: String,
value: "我是默认的内容"
}
}
})
向组件传递样式:
给组件传递样式:
有时候,我们不希望将样式在组件内固定不变,而是外部可以决定组件内部的样式。
这个时候,我们可以使用externalClasses
属性:
1.在Component对象中,由externalClasses属性定义要介绍的class
Component({
// 在组件中接收样式
externalClasses: ["info"]
})
2.在组件内的wxml中使用externalClasses属性中的class
<view class="section">
<view class="title">{{ title }}view>
<view class="content info">{{ content }}view>
view>
3.在页面中传入对应的class,并且给这个class设置样式
<section-info info="info" />
.info {
font-weight: 700;
}
组件向外传递事件 – 自定义事件
有时候是自定义组件内部发生了事件,需要告知组件的使用者(也就是说在外部监听组件内部的事件),这个时候可以使用自定义事件
首先, 监听组件内部的点击, 比如监听组件内部的title
<view class="section">
<view class="title" bindtap="onTitleTap">{{ title }}view>
<view class="content">{{ content }}view>
view>
在组件中监听事件, 在对应的事件函数中通过
this.triggerEvent
将事件发送出去
Component({
// 组件中的方法需要写在methods中
methods: {
onTitleTap() {
// 发送事件, 并传递一个aaa的参数
this.triggerEvent("titleTap", "aaa")
}
}
})
在使用组件的页面中, 接收组件传递出来的事件, 并绑定对应的事件处理函数
<section-info bind:titleTap="onTitleTap" />
在事件处理函数中, 可以获取到组件传递出来的参数
Page({
onTitleTap(event) {
console.log("页面中监听到组件的事件");
// 打印组件传递出来的参数
console.log(event.detail);
}
})
页面直接调用组件方法
如果我们想在父组件中调用子组件的方法, 可在父组件里调用 this.selectComponent ,获取子组件的实例对象。
调用时需要传入一个匹配选择器 selector,如:
this.selectComponent(".my-component")
。
Component({
// 组件中的方法需要写在methods中
methods: {
test() {
console.log("组件中的方法");
}
}
})
<section-info class="section" />
<button bindtap="onBtnTap">按钮button>
this.selectComponent
方法, 获取子组件实例对象Page({
onBtnTap() {
// 获取组件实例
const sectionInfo = this.selectComponent(".section")
// 调用组件中的方法
sectionInfo.test()
}
})
slot翻译为插槽:
在生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽。
插槽的目的是让我们原来的设备具备更多的扩展性。
比如电脑的USB我们可以插入U盘、硬盘、手机、音响、键盘、鼠标等等。
组件的插槽:
组件的插槽也是为了让我们封装的组件更加具有扩展性。
让使用者可以决定组件内部的一些内容到底展示什么。
例子:移动网站中的导航栏。
移动开发中,几乎每个页面都有导航栏。
导航栏我们必然会封装成一个插件,比如nav-bar组件。
一旦有了这个组件,我们就可以在多个页面中复用了。
但是,每个页面的导航是不一样的
除了内容和样式可能由外界决定之外,也可能外界想决定显示的方式
比如我们有一个组件定义了头部和尾部,但是中间的内容可能是一段文字,也可能是一张图片,或者是一个进度条。
在不确定外界想插入什么其他组件的前提下,我们可以在组件内预留插槽:
<view class="my-slot">
<view class="header">headerview>
<view class="content">
<slot>slot>
view>
<view class="footer">footerview>
view>
<my-slot>
<text>我是插入的文本text>
my-slot>
<my-slot>
<button size="mini">插入的按钮button>
my-slot>
<my-slot>
<input type="text" value="插入的表单" />
my-slot>
注意: 小程序的插槽是不支持默认值的
有时候为了让组件更加灵活, 我们需要定义多个插槽:
name
属性来区分<view class="mul-slot">
<view class="left">
<slot name="left">slot>
view>
<view class="center">
<slot name="center">slot>
view>
<view class="right">
<slot name="right">slot>
view>
view>
slot
属性指定要使用那个插槽<mul-slot>
<view slot="left">左边view>
<text slot="center">中间text>
<view slot="right">右边view>
mul-slot>
Component({
options: {
// 表示开启多个插槽
multipleSlots: true
}
})
组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。
其中,最重要的生命周期是
created
attached
detached
,包含一个组件实例生命流程的最主要时间点。
自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)。
Component({
// 组件的生命周期 推荐写到lifetimes中
lifetimes: {
created() {
console.log("组件被创建");
},
attached() {
console.log("组件被添加到组件树中");
},
detached() {
console.log("组件从组件树中被移除");
}
}
})
生命周期 | 参数 | 描述 |
---|---|---|
created | 无 | 在组件实例刚刚被创建时执行 |
attached | 无 | 在组件实例进入页面节点树时执行 |
ready | 无 | 在组件在视图层布局完成后执行 |
moved | 无 | 在组件实例被移动到节点树另一个位置时执行 |
detached | 无 | 在组件实例被从页面节点树移除时执行 |
error | Object Error | 每当组件方法抛出错误时执行 |
一般在created生命周期中, 发送网络请求; 在attached生命周期中获取DOM; 在detached中做回收组件的操作
其他生命周期了解即可
还有一些特殊的生命周期,它们并非与组件有很强的关联,但有时组件需要获知,以便组件内部处理。
这样的生命周期称为“组件所在页面的生命周期”,在
pageLifetimes
定义段中定义。
其中可用的生命周期包括:
生命周期 | 参数 | 描述 |
---|---|---|
show | 无 | 组件所在的页面被展示时执行 |
hide | 无 | 组件所在的页面被隐藏时执行 |
resize | Object Size | 组件所在的页面尺寸变化时执行 |
Component({
pageLifetimes: {
show: function() {
// 组件所在页面被展示
},
hide: function() {
// 组件所在页面被隐藏
},
resize: function(size) {
// 组件所在页面尺寸变化
}
}
})