组件化开发使用
组件通信使用过程
很多情况下,组件内展示的内容(数据、样式、标签),并不是在组件内写死的,而且可以由使用者来决定。
向组件传递数据:
大部分情况下,组件只负责布局和样式,内容是由使用组件的对象决定的;
所以,我们经常需要从外部传递数据给我们的组件,让我们的组件来进行展示;
如何传递呢?
使用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: {
onTitleTap() {
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: {
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">header</view>
<view class="content">
<slot></slot>
</view>
<view class="footer">footer</view>
</view>
<my-slot>
<text>我是插入的文本</text>
</my-slot>
<my-slot>
<button size="mini">插入的按钮</button>
</my-slot>
<my-slot>
<input type="text" value="插入的表单" />
</my-slot>
注意: 小程序的插槽是不支持默认值的
多个插槽的使用
有时候为了让组件更加灵活, 我们需要定义多个插槽:
- 在组件wxml定义多个插槽, 多个插槽需要通过
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: {
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) {
}
}
})
Component构造器总结
|