微信小程序——自定义组件
1,在创建的微信小程序项目的根目录上创建一个文件夹——component
2,在app.json上建立相关文件
可以看到,这个组件目录结构跟小程序普通页面结构是一样的,都是包含四个文件,但是.js和.json文件和普通页面略有不同。下面我们来看下每个文件的构成。
3,介绍
js文件:
// js文件
Component({
/**
* 组件的属性列表
*/
properties: {},
/**
* 组件的初始数据
*/
data: {},
/**
* 组件的方法列表
*/
methods: {}
})
json文件:json文件,一定要注意,组件json文件中的component必须为true,这点和普通页面不同。
{
"component": true
}
wxml和wxss文件就不用说了,用来写html和css代码的。
在页面上引用该组件
在引用组件的页面里的json文件中增加引用组件配置
{
"usingComponents": {
"commonNav": "../../components/commonNav/commonNav"
}
}
然后在引用页面的wxml中添加组件
<view>
<commonNav></commonNav> //注意这里的名字要和json文件中的组件名字保持一致
</view>
组件的属性
就是porperties大括号中的部分,开发者可以在这个里面自定义属性。这里我添加三个属性width,height,backgroundcolor
...
properties: {
// 组件显示区域的宽度 (rpx)
width: {
type: Number,
value: 750 // 组件默认宽度 即整屏宽
},
// 组件显示区域的高度 (rpx)
height: {
type: Number,
value: 60 // 组件默认高度
},
// 组件背景颜色
backgroundcolor: {
type: String,
value: 'red'
}
}
...
官方文档的介绍:
Component({
behaviors: [],
// 属性定义(详情参见下文)
properties: {
myProperty: { // 属性名
type: String,
value: ''
},
myProperty2: String // 简化的定义方式
},
data: {}, // 私有数据,可用于模板渲染
lifetimes: {
// 生命周期函数,可以为函数,或一个在methods段中定义的方法名
attached: function () { },
moved: function () { },
detached: function () { },
},
// 生命周期函数,可以为函数,或一个在methods段中定义的方法名
attached: function () { }, // 此处attached的声明会被lifetimes字段中的声明覆盖
ready: function() { },
pageLifetimes: {
// 组件所在页面的生命周期函数
show: function () { },
hide: function () { },
resize: function () { },
},
methods: {
onMyButtonTap: function(){
this.setData({
// 更新属性和数据的方法与更新页面数据的方法类似
})
},
// 内部方法建议以下划线开头
_myPrivateMethod: function(){
// 这里将 data.A[0].B 设为 'myPrivateData'
this.setData({
'A[0].B': 'myPrivateData'
})
},
_propertyChange: function(newVal, oldVal) {
}
}
})
在组件的wxml引用属性
<view
style='background:{{backgroundcolor}}; width:{{width}}rpx; height:{{height}}rpx;'>
view from component
</view>
接下来,我们引用了组件的页面上加上属性
<view>view form index</view>
<commonNav width='520' backgroundcolor='green'></commonNav>
如果你愿意,还可以加上字体颜色等其他属性。
最后还要注意的是,type类型常用的有:String、Number、Boolean、Object等属性
组件的生命周期
// js文件
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
},
//在组件实例刚刚被创建时执行,注意此函数中不能使用setData操作
created: function () {
console.log('created')
},
// 在组件实例进入页面节点树时执行
attached: function () {
console.log('attached')
},
//在组件在视图层布局完成后执行
ready: function () {
console.log('ready')
},
//在组件实例被移动到节点树另一个位置时执行
moved: function () {
console.log('moved')
},
// 在组件实例被从页面节点树移除时执行
detached: function () {
console.log('detached')
},
/**
* 组件的方法列表
*/
methods: {
}
})
利用这些组件生命周期函数,我们可以做数据的初始化,销毁等等工作。
宿主(引用页面)生命周期
在组件中同样还可以调用其宿主生命周期函数,注意下面的三个函数都限定了最低版本库
...
pageLifetimes: {
//组件所在的页面被展示时执行 最低版本2.2.3
show: function () {
console.log('页面被展示')
},
//组件所在的页面被隐藏时执行 最低版本2.2.3
hide: function () {
console.log('页面被隐藏')
},
//这个函数一般使用场景较少,了解就可以了 最低版本2.4.0
resize: function (size) {
console.log('页面尺寸变化')
}
}
...
slot节点
看到这里,你会发现,组件其实就是一个自定义view,只不过这个view封装了我们自己的某些业务逻辑。既然是view,能不能包裹其他view?例如下面这种写法:
<view>view form index</view>
<commonNav width='520' backgroundcolor='green'>
<view>view warp by component-view</view>
</commonNav
如果只是修改wxml,显然是不会有效果的。而组件中的slot节点则是用来解决这个问题的。接下来看代码:
组件js文件:
...
options: {
multipleSlots: true // 在组件定义时的选项中启用slot支持
}
...
组件wxml文件
<view style='background:{{backgroundcolor}};width:{{width}}rpx;height:{{height}}rpx;'>view from component</view>
<slot name='content'></slot>//增加slot节点
宿主(引用组件的页面)只需要修改下wxml文件
<view>view form index</view>
<commonNav width='520' backgroundcolor='green'>
<view slot='content'>view warp by component-view</view>
</commonNav>
可以看到,被组件包裹的view已经能正确在页面显示。