自定义组件
自定义组件
创建自定义组件
在项目根目录创建 components 文件夹,每个组件由 4 个文件组成:.js、.json、.wxml、.wxss。
components/
├── header/
│ ├── header.js
│ ├── header.json
│ ├── header.wxml
│ └── header.wxss
└── footer/
├── footer.js
├── footer.json
├── footer.wxml
└── footer.wxsscomponents/
├── header/
│ ├── header.js
│ ├── header.json
│ ├── header.wxml
│ └── header.wxss
└── footer/
├── footer.js
├── footer.json
├── footer.wxml
└── footer.wxss组件需要在 .json 文件中声明为组件:
json
{
"component": true
}{
"component": true
}注册组件
全局注册:在 app.json 中配置 usingComponents。
json
{
"usingComponents": {
"my-header": "/components/header/header"
}
}{
"usingComponents": {
"my-header": "/components/header/header"
}
}页面局部注册:在页面的 .json 文件中配置。
json
{
"usingComponents": {
"my-header": "/components/header/header"
}
}{
"usingComponents": {
"my-header": "/components/header/header"
}
}使用组件
html
<!-- 页面 wxml -->
<my-header title="首页" /><!-- 页面 wxml -->
<my-header title="首页" />组件 JS 定义
js
Component({
properties: {
title: {
type: String,
value: '默认标题'
}
},
data: {
count: 0
},
methods: {
handleTap() {
this.setData({
count: this.data.count + 1
})
// 触发自定义事件,向父组件传递数据
this.triggerEvent('change', { count: this.data.count })
}
}
})Component({
properties: {
title: {
type: String,
value: '默认标题'
}
},
data: {
count: 0
},
methods: {
handleTap() {
this.setData({
count: this.data.count + 1
})
// 触发自定义事件,向父组件传递数据
this.triggerEvent('change', { count: this.data.count })
}
}
})html
<!-- 组件 wxml -->
<view class="header">
<text>{{title}}</text>
<button bindtap="handleTap">点击</button>
</view><!-- 组件 wxml -->
<view class="header">
<text>{{title}}</text>
<button bindtap="handleTap">点击</button>
</view>组件间通信与数据传递
| 方式 | 说明 |
|---|---|
| 属性绑定 | 父组件通过 properties 向子组件传递数据 |
| 事件触发 | 子组件通过 triggerEvent 向父组件传递数据 |
| 获取组件实例 | 父组件通过 this.selectComponent(id) 获取子组件实例 |
父 -> 子:属性绑定
html
<!-- 父组件 wxml -->
<my-child prop-a="{{dataA}}" prop-b="{{dataB}}" /><!-- 父组件 wxml -->
<my-child prop-a="{{dataA}}" prop-b="{{dataB}}" />子 -> 父:事件触发
js
// 子组件触发事件
this.triggerEvent('myevent', { value: 'hello' }, { bubbles: true })
// 父组件监听事件
// <my-child bind:myevent="onMyEvent" />
// 父组件处理事件
onMyEvent(e) {
console.log(e.detail.value) // 'hello'
}// 子组件触发事件
this.triggerEvent('myevent', { value: 'hello' }, { bubbles: true })
// 父组件监听事件
// <my-child bind:myevent="onMyEvent" />
// 父组件处理事件
onMyEvent(e) {
console.log(e.detail.value) // 'hello'
}获取组件实例
js
// 父组件中获取子组件实例
const child = this.selectComponent('#child-id')
child.setData({ name: '张三' })// 父组件中获取子组件实例
const child = this.selectComponent('#child-id')
child.setData({ name: '张三' })组件生命周期
js
Component({
lifetimes: {
created() {
// 组件实例刚被创建,不能使用 setData
},
attached() {
// 组件进入页面节点树,可以 setData
},
ready() {
// 组件在视图层布局完成后触发
},
moved() {
// 组件被移动到节点树另一个位置
},
detached() {
// 组件从页面节点树移除
}
}
})Component({
lifetimes: {
created() {
// 组件实例刚被创建,不能使用 setData
},
attached() {
// 组件进入页面节点树,可以 setData
},
ready() {
// 组件在视图层布局完成后触发
},
moved() {
// 组件被移动到节点树另一个位置
},
detached() {
// 组件从页面节点树移除
}
}
})也可以使用旧版生命周期写法:
js
Component({
created() {},
attached() {},
ready() {}
})Component({
created() {},
attached() {},
ready() {}
})组件所在页面的生命周期
js
Component({
pageLifetimes: {
show() {
// 页面被展示时触发
},
hide() {
// 页面被隐藏时触发
},
resize(size) {
// 页面尺寸变化时触发
}
}
})Component({
pageLifetimes: {
show() {
// 页面被展示时触发
},
hide() {
// 页面被隐藏时触发
},
resize(size) {
// 页面尺寸变化时触发
}
}
})组件插槽(slot)
单个插槽
html
<!-- 组件 wxml -->
<view>
<slot name="header" />
<view>默认内容</view>
<slot name="footer" />
</view><!-- 组件 wxml -->
<view>
<slot name="header" />
<view>默认内容</view>
<slot name="footer" />
</view>html
<!-- 使用组件 -->
<my-comp>
<view slot="header">头部内容</view>
<view slot="footer">底部内容</view>
</my-comp><!-- 使用组件 -->
<my-comp>
<view slot="header">头部内容</view>
<view slot="footer">底部内容</view>
</my-comp>启用多个插槽
js
// 组件 js
Component({
options: {
multipleSlots: true
}
})// 组件 js
Component({
options: {
multipleSlots: true
}
})组件样式隔离
默认情况下,组件的样式只对当前组件生效,不会影响外部。
js
Component({
options: {
styleIsolation: 'isolated' // 默认值
}
})Component({
options: {
styleIsolation: 'isolated' // 默认值
}
})| 值 | 说明 |
|---|---|
isolated | 组件内外样式互不影响(默认) |
apply-shared | 页面样式会影响到组件 |
shared | 组件和页面样式互相影响 |
数据监听器(observers)
js
Component({
properties: {
a: Number,
b: Number
},
observers: {
'a, b': function (a, b) {
// 当 a 或 b 变化时触发
this.setData({
sum: a + b
})
},
'obj.**': function (obj) {
// 监听对象深层属性变化
console.log(obj)
}
}
})Component({
properties: {
a: Number,
b: Number
},
observers: {
'a, b': function (a, b) {
// 当 a 或 b 变化时触发
this.setData({
sum: a + b
})
},
'obj.**': function (obj) {
// 监听对象深层属性变化
console.log(obj)
}
}
})组件间关系(relations)
js
// 父组件
Component({
relations: {
'./child': {
type: 'child',
linked(target) {
// 每次子组件被插入时触发
}
}
}
})
// 子组件
Component({
relations: {
'./parent': {
type: 'parent',
linked(target) {
// 每次被插入到父组件时触发
}
}
}
})// 父组件
Component({
relations: {
'./child': {
type: 'child',
linked(target) {
// 每次子组件被插入时触发
}
}
}
})
// 子组件
Component({
relations: {
'./parent': {
type: 'parent',
linked(target) {
// 每次被插入到父组件时触发
}
}
}
})
Cao Note