一、组件
组件的概念在其他文章里已经记录过就不多说了,其主要是对画面中的某一部分布局进行提取从而提高复用性
1.1. 定义组件
组件的文件结构如下:
- 组件布局文件
wxml
- 组件逻辑文件
js
- 组件配置文件
json
- 组件样式文件
wxss
看到上面的组件文件结构后,可能会有疑问,这不是跟页面文件一样吗,没错,它们的结构就是一样的,不只结构
一样,语法也一样,真正用来区分这四个文件是页面文件还是组件文件的关键,其实取决于逻辑文件 js
中调用的函数,
我们之前调用 Page()
函数来指明相关文件为页面文件,现在需要调用 Component()
函数来指明相关文件为组件文件
与页面文件的函数 Page()
一样,Component()
函数也需要一个对象类型的参数,这个参数对象同样也包含了预定义
的属性和生命周期函数,常见的预定义内容如下,更多请参照 微信小程序-自定义组件:
类型 | 名称 | 描述 |
---|---|---|
属性 | data | 对象类型,组件的页面中需要使用的数据可以定义为该对象的属性 |
属性 | properties | 对象类型,可供外部传值的属性,组件的页面中也可以直接使用 |
属性 | methods | 对象类型,自定义函数可以定义在该对象内 |
方法 | ready | 组件生命周期函数-在组件布局完成后执行 |
示例:创建组件
1. 一般常以如下目录结构管理组件文件
2. 定义组件逻辑文件:
// 调用组件函数
Component({
// 定义组件的页面中要使用的数据
data: {
message: '这是定义在组件内的消息!'
},
// 组件内的自定义方法
methods: {
// 页面按钮点击事件
handleTap() {
const messageChange = '组件函数改变了消息!'
this.setData({
message: messageChange
})
}
}
})
3. 定义组件布局文件,语法与页面布局文件一样:
<view>{{message}}</view>
<button bind:tap="handleTap">修改消息</button>
1.2. 页面布局文件中使用组件
页面布局文件中想使用定义好的组件只需要两步:
- 将要使用的组件声明在页面配置文件的
usingComponents
属性中,并给组件重新命名 - 在布局文件内通过重命名后的组件名调用组件
示例:页面布局文件中使用上面定义好的组件
1. 在页面配置文件中声明要使用的组件,../../components/home/Home
是组件文件的相对路径,HOME
是给组件重新
命名,这样页面布局文件中就可以使用这个名字来调用组件了:
{
"usingComponents": {
"HOME":"../../components/home/Home"
}
}
2. 在布局文件内通过重命名后的组件名调用组件:
<HOME></HOME>
3. 运行效果:
二、组件传值
2.1. 向组件内传值
向组件内传值指的是,引用组件的页面向组件内部传值,也称父传子,使用步骤如下:
- 在组件逻辑文件中,将接收传值的属性定义在组件函数
Component()
的参数对象的properties
属性中 - 在页面布局文件使用组件时,通过
组件传值属性="值"
的方式进行传值
示例:向组件内传值
1. 组件部分
在组件逻辑文件中定义接收外部传值的属性
// 调用组件函数
Component({
// 定义接收外部传值的属性
properties: {
message: ''
}
})
2. 页面部分
(1) 页面配置文件中声明要使用的组件:
{
"usingComponents": {
"HOME":"../../components/home/Home"
}
}
(2) 在页面逻辑文件中定义页面数据,用来演示页面数据传值:
Page({
// 页面数据
data: {
pageData: '传给组件的值'
}
});
(3) 分别使用常量的方式和页面数据的方式向组件内部传值:
<!-- 使用常量的方式传值 -->
<HOME message="传给组件的值"></HOME>
<!-- 使用页面数据的方式传值 -->
<HOME message="{{pageData}}"></HOME>
3. 运行效果:
2.2. 组件向外传值
组件向外传值也称子传父,最常见的就是下面的场景:
场景分析:主页面有两部分,第一部分引入分类组件,第二部分根据组件选择的分类在主页面中显示具体分类内
容,这就要求主页面必须知道组件中具体选择了哪个分类,这就是典型的子传父使用场景
组件向外传值只需要两步:
- 组件内使用
this.triggerEvent('自定义事件名', 值)
发布一个自定义事件 - 页面中使用组件时,在组件标签内绑定自定义事件,然后使用
事件对象.detail
从事件对象中获取组件传递的值
示例:组件向外传值
1. 组件部分
在组件逻辑文件中发布自定义事件
// 调用组件函数
// 调用组件函数
Component({
// 生命周期函数 - 组件创建完毕后回调
ready(){
// 发布自定义事件
this.triggerEvent('myEvent', '子组件传递的内容')
}
})
2. 页面部分
(1) 页面配置文件中声明要使用的组件:
{
"usingComponents": {
"HOME":"../../components/home/Home"
}
}
(2) 页面逻辑文件中声明自定义事件的处理函数,并获取组件传递的值:
Page({
// 页面数据
data: {
message: ''
},
// 监听组件的自定义事件
handleEvent(e){
this.setData({
// 获取传递组件的值
message:e.detail
})
}
});
(3) 页面布局文件中,使用组件时在组件标签内绑定自定义事件:
<!-- 使用组件时监听自定义事件 -->
<HOME bind:myEvent="handleEvent"></HOME>
<!-- 展示组件传递的值 -->
<view>{{message}}</view>
3. 运行效果:
三、插槽
插槽的功能是让组件中的一部分布局由父页面添加,这样可以让组件有更高的复用性,目前版本的微信小程
序 ( v2.23.4 ) 中,还不支持插槽的默认布局,这一点与 Vue 不同
3.1. 单插槽
使用单插槽的方式非常简单,在组件布局时,将想让父页面传入的部分使用 <slot>
标签占位,然后在父页面使用组
件时,在组件标签中间传入布局即可
示例: 单插槽
1. 组件部分
在组件布局文件中使用 <slot>
占位,由父组件传入具体布局:
<view style="display: flex; border:1px solid black;">
<!-- 组件左侧布局 -->
<view style="flex:2; text-align: center; ">组件固定左侧内容</view>
<!-- 组件中间布局 - 插槽由引入组件的页面设置 -->
<view style="flex: 3; text-align: center;">
<slot></slot>
</view>
<!-- 组件右侧布局 -->
<view style="flex:2; text-align: center;">组件固定右侧内容</view>
</view>
2. 页面部分
在页面布局文件中,使用组件时,在组件标签内,传入具体的布局替换掉 <slot>
占位:
<!-- 第一次引入组件 -->
<HOME>
<view>父页面设置的布局内容1</view>
</HOME>
<!-- 第二次引入组件 -->
<HOME>
<view>父页面设置的布局内容2</view>
</HOME>
3. 运行效果:
3.2. 多插槽(具名插槽)
当组件中有多个地方的布局都需要父组件传入的情况,就可以使用具名插槽,使用方式也很简单:
- 在组件布局文件中使用
name
属性给每个<slot>
占位区定义名称 - 在组件逻辑文件的
Component
函数的参数中添加属性options: { multipleSlots: true }
,设置允许多插槽 - 在父页面布局文件中,向组件内传入布局时,通过
slot
属性指定占位区名称,替换掉组件中对应的内容
示例:多插槽
1. 组件部分
(1) 在组件布局文件中使用 <slot>
占位,并设置占位名称,由父组件指名传入具体布局:
<view style="display: flex; border:1px solid black;">
<!-- 组件左侧布局 -->
<view style="flex:2; text-align: center; ">组件固定左侧内容</view>
<!-- 组件中间布局 - 插槽由引入组件的页面设置 -->
<view style="flex: 3; text-align: center;">
<slot name="center"></slot>
</view>
<!-- 组件右侧布局 - 插槽由引入组件的页面设置 -->
<view style="flex:2; text-align: center;">
<slot name="right"></slot>
</view>
</view>
(2) 在组件逻辑文件中设置允许使用多插槽:
Component({
options: {
multipleSlots: true
}
})
2. 页面部分
在页面布局文件中,使用组件时,在组件标签内,通过 slot
属性指定要替换的占位区名称,替换掉对应的占位:
<!-- 第一次引入组件 -->
<HOME>
<view slot="center">父页面设置的布局内容1</view>
<view slot="right">父页面设置的布局内容2</view>
</HOME>
3. 运行效果: