本篇博客介绍在微信小程序中自定义组件时需要的注意事项,以自定义select下拉选项卡为例
自定义组件官方文档介绍:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/
Component组件官方文档介绍:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html
一、创建组件
1、新建组件文件
在components文件夹下新建目录select,创建select下拉选项卡组件

2、自定义组件样式及js
①select.wxml文件
<view class='com-selectBox'>
<view class='com-sContent' bindtap='selectToggle'>
<view class='com-sTxt'>{{nowText}}</view>
<image src='/images/down.png' class='com-sImg' animation="{{animationData}}"></image>
</view>
<view class='com-sList' wx:if="{{selectShow}}">
<view wx:for="{{propArray}}" data-index="{{index}}" wx:key="id"
class='com-sItem {{showid==index?"check-style":""}}' bindtap='setText'>{{item.text}}</view>
</view>
</view>
tips: (1) animation="{{animationData}}" 是下箭头的动画效果
(2) data-index="{{index}}" 是当前元素被点击时的索引
(3) selectToggle是模仿下拉选项框隐藏和显示的事件。
(4) setText是模仿下拉选项框选择子项之后,设置内容的事件。
(5) selectShow是表示option选项显示与否
②select.wxss文件
.com-selectBox {
100%;
}
.com-sContent {
border-top: 1px solid #e2e2e2;
background: white;
color: #7a7a7a;
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx 0;
}
.com-sImg {
10%;
height: 9px;
transition: all 0.3s ease;
}
.com-sTxt {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 28rpx;
}
.com-sList {
background: white;
33.3%;
position: absolute;
border: 1px solid #e2e2e2;
border-top: none;
box-sizing: border-box;
z-index: 3;
overflow: auto;
}
.com-sItem {
height: 30px;
line-height: 30px;
border-top: 1px solid #e2e2e2;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 28rpx;
color: #7a7a7a;
}
.com-sItem:first-child {
border-top: none;
}
.check-style{
color: red;
}
③selece.js
Component({
// 组件的属性列表
properties: {
// 页面传入组件的数据
propArray: {
type: Array,
},
nowText: {
type: null,
}
},
// 组件的初始数据
data: {
selectShow: false, //初始option不显示
firstText: '', //select的标题文字
animationData: {}, //右边箭头的动画
showid: 0,//当前选中索引
},
// 组件声明周期
lifetimes: {
attached: function() {
// 在组件实例进入页面节点树时执行
this.setData({
firstText: this.properties.nowText,//将获取到的初始值存储起来
});
},
detached: function() {
// 在组件实例被从页面节点树移除时执行
},
},
// 组件的方法列表
methods: {
//option的显示与否
selectToggle: function() {
var nowShow = this.data.selectShow; //获取当前option显示的状态
//创建动画
var animation = wx.createAnimation({
timingFunction: "ease"//动画以低速开始,然后加快,在结束前变慢
})
this.animation = animation;
if (nowShow) {//option不显示
animation.rotate(0).step();//箭头不旋转
this.setData({
animationData: animation.export()
})
} else {//option显示
animation.rotate(180).step();//箭头旋转180度
this.setData({
animationData: animation.export()
})
}
this.setData({
selectShow: !nowShow
})
},
//设置内容
setText: function(e) {
var nowData = this.properties.propArray; //引入组件的页面传过来的数据
var nowIdx = e.target.dataset.index; //当前点击的索引
var nowTexts = nowData[nowIdx].text; //当前点击的内容
//再次执行动画,注意这里是this.animation来使用动画
this.animation.rotate(0).step();
//如果点击的是“全部”,显示标题文字
if (nowIdx == "0") {
this.setData({
nowText: this.data.firstText,
showid: nowIdx,
selectShow: false,
animationData: this.animation.export(),
})
} else {//否则显示点击内容
this.setData({
nowText: nowTexts,
showid: nowIdx,
selectShow: false,
animationData: this.animation.export(),
})
}
}
}
})
tips: (1) 如果想对data里的数据做初始化,必须自己给他初始值。
(2) 不要把data和properties里的变量设置成同一个名字,如果他们名字相同,properties里的会覆盖data里的
(3) 组件声明周期中的 attached 方法在组件实例进入页面节点树时执行,我理解为和页面生命周期中的 onLoad 方法效果一致
(4) Animation动画官方文档:https://developers.weixin.qq.com/miniprogram/dev/api/ui/animation/Animation.html
二、使用组件
1、引入组件
在使用组件页面的json文件中配置
"usingComponents": {
"select": "/components/select/select"
}
tips: 注意路径是否正确, / 单斜杠表示根目录,是绝对路径。
2、页面使用组件
<view class="top">
<select prop-array='{{timeArray}}' now-text='{{invetime}}'></select>
<select prop-array='{{termArray}}' now-text='{{term}}'></select>
<select prop-array='{{moneybackArray}}' now-text='{{moneyback}}'></select>
</view>
tips: prop-array为自定义的属性名,和组件所在的 js 中properties中的属性是对应的。
在 properties 定义的属性中,属性名采用驼峰写法(例如:propArray)。
在引入组件的 wxml 中,指定属性值时则对应使用连字符写法(例如:prop-array=”…”)。
3、传入组件所需数据
在引用组件页面的.js文件中的data中传入数据
data: {
invetime: '投资时间',
term: '标的期限',
moneyback: '是否回款',
timeArray: [{
"id": "0",
"text": "全部"
}, {
"id": "1",
"text": "3个月内"
}, {
"id": "2",
"text": "6个月内"
}, {
"id": "3",
"text": "12个月内"
}]
}
效果图:

参考博客:https://www.cnblogs.com/zjjDaily/p/9548433.html
END!