# 自定义组件
自定义组件,和vue中自定义组件类似,都是封装公共组件,减少代码开发量。
# 1、创建自定义组件
- 新建自定义组件的文件 必须包含 .wxml .wxss .js .json
- 定义组件.json文件必须定义 "component": true,才可以
- 其他组件使用必须在.json文件内进行 注册引入,然后才能在页面中使用组件标签
- 在组件wxss中不应使用ID选择器、属性选择器和标签名选择器
- 因为 WXML 节点标签名只能是小写字母、中划线和下划线的组合,所以自定义组件的标签名也只能包含这些字符。
├── components # 业务公共组件
│ ├── PictureView # PictureView组件
│ │ ├── index.js # 页面逻辑处理
│ │ ├── index.json # 页面配置
│ │ ├── index.wxml # html
│ │ ├── index.wxss # css
│ │ └── index.less # less/sass
# 2、组件的引用
组件引用必须在.json中进行注册才能使用
// .json
{
"navigationBarTitleText": "首页",
"usingComponents": {
"picture-view": "../../components/picture-view/index"
}
}
# 3、组件之间传值
<view class="index">
<picture-view url="hello world"></picture-view>
</view>
// components/picture/index.js
Component({
/**
* 组件的属性列表
* 父组件传入的值,相当于prop
*/
properties: {
url: {
type: String,
value: 'default value'
}
},
// 声明周期
lifetimes: {
// 页面已经创建好,执行一些初始化操作,如果获取数据、设置数据
attached: function() {
console.log(this.data.url); // hello world
}
}
})
# 4、组件事件触发
子组件触发数据
<view class="picture">
<button bindtap="onTap">触发自定义“myevent”事件</button>
</view>
// components/picture/index.js
Component({
/**
* 组件的属性列表
* 父组件传入的值,相当于prop
*/
properties: {
url: {
type: String,
value: 'default value'
}
},
// 声明周期
lifetimes: {
// 页面已经创建好,执行一些初始化操作,如果获取数据、设置数据
attached: function() {
console.log(this.data.url); // hello world
}
},
/**
* 组件的方法列表
*/
methods: {
// 提交自定义事件
onTap: function(){
const params = {
type: 1
}
this.triggerEvent('myevent', params)
}
}
})
父组件接收
<view class="index">
<picture-view url="hello world" bind:myevent="onMyEvent"></picture-view>
</view>
// 父组件.js
// 接收组件自定义事件
onMyEvent(e) {
console.log(e.detail); // e.detail 传入的参数 {type: 1}
}
# 5、组件的声明周期
组件重要的生命周期是 created attached detached
- created 在组件实例刚刚被创建时执行, 此时还不能调用 setData,也不能获取properties
- attached 页面已经创建好,执行一些初始化操作,如果获取数据、设置数据。
- detached在组件离开页面触发。
以前低版本声明周期都是直接定义在最外层的,自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)。
// components/picture/index.js
Component({
/**
* 组件的属性列表
* 父组件传入的值,相当于prop
*/
properties: {
url: {
type: String,
value: 'default value'
}
},
/**
* 私有数据-组件的初始数据
*/
data: {
currentId: '123'
},
// 组件声明周期
// 自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)。
lifetimes: {
// 在组件实例刚刚被创建时执行, 此时还不能调用 setData
created: function() {
console.log(this.data); // 获取data数据,但properties数据还不能获取
},
// 页面已经创建好,执行一些初始化操作,如果获取数据、设置数据
attached: function() {
console.log(this.data); // 获取data数据
this.setData({
currentId: '456'
})
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
}
}
})
# 6、behaviors
behaviors相当于vue的mixins的混入
# 7、事件监听
observers数据监听器可以用于监听和响应任何属性和数据字段的变化,可以监听变量,对象,数组的变化。相当于vue中的watch和computed的结合。
observers数据监听 (opens new window)
// components/picture/index.js
Component({
/**
* 组件的属性列表
* 父组件传入的值,相当于prop
*/
properties: {
url: {
type: String,
value: 'default value'
}
},
/**
* 私有数据-组件的初始数据
*/
data: {
currentId: '123',
msg: 'hello world'
},
// 组件声明周期
// 自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)。
lifetimes: {
// 在组件实例刚刚被创建时执行, 此时还不能调用 setData
created: function() {
console.log(this.data); // 获取data数据,但properties数据还不能获取
},
// 页面已经创建好,执行一些初始化操作,如果获取数据、设置数据
attached: function() {
console.log(this.data); // 获取data数据
this.setData({
currentId: '456'
})
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
}
},
// 数据监听
observers: {
'numberA, numberB': function(numberA, numberB) {
// 在 numberA 或者 numberB 被设置时,执行这个函数
this.setData({
sum: numberA + numberB
})
}
}
})
# 8、组件的使用
子组件:
.wxml
<!--components/picture-view/index.wxml-->
<view class="picture">
<image src="{{url}}"></image>
<button bindtap="onTap">触发自定义“myevent”事件</button>
</view>
.js
// components/picture/index.js
Component({
/**
* 组件的属性列表
* 父组件传入的值,相当于prop
*/
properties: {
url: {
type: String,
value: 'default value'
}
},
/**
* 私有数据-组件的初始数据
*/
data: {
currentId: '123',
msg: 'hello world',
student: {
age: 18,
name: 'lihua'
}
},
// 组件声明周期
// 自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)。
lifetimes: {
// 在组件实例刚刚被创建时执行, 此时还不能调用 setData
created: function() {
console.log(this.data); // 获取data数据,但properties数据还不能获取
},
// 页面已经创建好,执行一些初始化操作,如果获取数据、设置数据
attached: function() {
console.log(this.data); // 获取data数据
this.setData({
currentId: '456'
})
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
},
/**
* 组件的方法列表
*/
methods: {
// 提交自定义事件
onTap: function(){
const params = {
type: 1
}
this.triggerEvent('myevent', params)
}
},
// 数据监听
observers: {
'currentId': function(currentId) {
console.log(currentId); // 456
}
}
})
.json
{
"component": true,
"usingComponents": {}
}
父组件:
.wxml
<picture-view url="{{childUrl}}" bind:myevent="onMyEvent"></picture-view>
.js
// index.js
Page({
data: {
childUrl: '../../assets/images/图层-1.jpg'
},
// 组件自定义事件
onMyEvent(e) {
console.log(e.detail); // e.detail 传入的参数
}
})
.json
{
"navigationBarTitleText": "首页",
"usingComponents": {
"picture-view": "../../components/picture-view/index"
}
}
← 微信开发者工具使用插件 自定义tabbar →