本篇博客介紹在微信小程序中自定義組件時需要的注意事項,以自定義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 {
width: 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 {
width: 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;
width: 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!
