本文將結(jié)合案例出牧,來闡述自定義組件實(shí)現(xiàn)掘宪。點(diǎn)擊我查看完整項(xiàng)目
先來上圖
自定義控件.png
這個(gè)是一個(gè)購物車的數(shù)量組件蛾扇。主要思路:
1、可以手動(dòng)的輸入具體的數(shù)量
2魏滚、可自定義設(shè)置最小值屁桑、和最大值。當(dāng)是最小值時(shí)栏赴,“-”號(hào)置灰,并不可點(diǎn)擊靖秩。當(dāng)是最大值時(shí)须眷,“+”號(hào)置灰,并不可點(diǎn)擊沟突。
3花颗、當(dāng)手動(dòng)輸入“0”開頭的數(shù)字時(shí),自行過濾惠拭,禁止輸入扩劝,只值輸入非0數(shù)字。
4职辅、當(dāng)手動(dòng)輸入數(shù)字大于最大值時(shí)棒呛,輸入框失去焦點(diǎn),默認(rèn)將輸入值置為最大值域携〈孛耄或者當(dāng)手動(dòng)輸入數(shù)字小于最小值時(shí),輸入框失去焦點(diǎn)秀鞭,默認(rèn)將輸入值置為最小值
5趋观、如果屬性值minNum最小值、或者maxNum最大值設(shè)置為NaN锋边,則表示最小值和最大值的大小沒有輸入的限制
6皱坛、默認(rèn)最小值和最大值是沒有限制的,可以隨便輸入
一豆巨、使用自定義組件的方式
1剩辟、js文件中:
輸入框數(shù)值變化最終響應(yīng)的函數(shù)
showNumber: function (e) {
var num = e.detail.num
},
2、json文件中:
{
"usingComponents": {
/**
* key:自定義組件的別名,在使用組件時(shí)用到抹沪。相當(dāng)于Android自定義控件在xml文件中的申明的命名空間
* value: 自定義組件的全路徑
*/
"component-option-num": "/component/optionNumber-component/optionNumber-component"
}
}
3刻肄、wxml文件中:
1、這里設(shè)置了最小值是0融欧,最大值是20敏弃。
2、bindoptionNum:是由bind+"optionNum"自定義組件回調(diào)函數(shù)的名稱組成噪馏。當(dāng)自定義組件的函數(shù)回調(diào)是麦到,這個(gè)屬性指定的方法bindoptionNum將被響應(yīng)。并可以獲取傳入的值
<component-option-num bindoptionNum="showNumber" minNum="0" maxNum="20"></component-option-num>
一欠肾、自定義組件的定義
1瓶颠、 對(duì)外提供的自定義屬性值
/**
* 組件的屬性列表
*/
properties: {
//最小值
minNum:{
type:Number,
value: NaN
},
//最大值
maxNum:{
type:Number,
value:NaN
},
},
2、 組件內(nèi)部使用的數(shù)據(jù)
/**
* 組件的初始數(shù)據(jù)
*/
data: {
num: 0, //輸入框顯示的數(shù)量
disabledMin: false, //"-"是否可點(diǎn)擊刺桃,true 不能點(diǎn)擊
disabledMax:false //"+"是否可點(diǎn)擊粹淋,true 不能點(diǎn)擊
},
3、 增加數(shù)量方法
_add: function (e) {
let num = parseInt(this.data.num) + 1
if (this.checkIsMaxNum(num)) {
/**
* 大于最大數(shù)值瑟慈,將輸入框的值設(shè)置為最大值桃移,
* 且"+"不能點(diǎn)擊、"-"可點(diǎn)擊
*/
num = this.data.maxNum
this.data.disabledMax = true
this.data.disabledMin = false
}else {
this.data.disabledMin = false
this.data.disabledMax = false
}
this.setData({
num: num,
disabledMin: this.data.disabledMin,
disabledMax: this.data.disabledMax
})
//回調(diào)optionNum方法葛碧,將輸入框num值傳遞給使用該組件的函數(shù)
this.triggerEvent('optionNum', { num: num })
},
4借杰、減少數(shù)量
_reduce: function (e) {
let num, disabledMin, disabledMax
num = parseInt(this.data.num) - 1
if (this.checkIsMinNum(num)) { //小于最小數(shù)
/**
* 小于最小數(shù)值,將輸入框的值設(shè)置為最小值进泼,
* 且"-"不能點(diǎn)擊蔗衡、"+"可點(diǎn)擊
*/
num = this.data.minNum
disabledMin = true
disabledMax = false
}else{
disabledMin = false
disabledMax = false
}
this.setData({
num: num,
disabledMin: disabledMin,
disabledMax: disabledMax
})
//回調(diào)optionNum方法,將輸入框num值傳遞給使用該組件的函數(shù)
this.triggerEvent('optionNum',{num:num})
},
5乳绕、手動(dòng)輸入數(shù)量
_input: function (e) {
let val = e.detail.value
//1绞惦、先用正則校驗(yàn)輸入的第一個(gè)數(shù)字,當(dāng)手動(dòng)輸入“0”開頭的數(shù)字時(shí)刷袍,自行過濾翩隧,禁止輸入,只值輸入非0數(shù)字
var num = val.replace(/^[0]+[0-9]*$/gi, "")
/**
* 大于最大數(shù)值呻纹,將輸入框的值設(shè)置為最大值堆生,且"+"不能點(diǎn)擊、"-"可點(diǎn)擊雷酪。反之亦然
*/
if (this.checkIsMinNum(num)) { //小于最小數(shù)
this.data.disabledMin = true
this.data.disabledMax = false
} else if (this.checkIsMaxNum(num)) { //大于最大數(shù)
this.data.disabledMax = true
this.data.disabledMin = false
} else {
this.data.disabledMin = false
this.data.disabledMax = false
}
this.setData({
num: num,
disabledMin: this.data.disabledMin,
disabledMax:this.data.disabledMax
})
this.triggerEvent('optionNum', { num: num })
},
6淑仆、失去焦點(diǎn)
_blur:function(e){
let val = e.detail.value
let num = val.replace(/^[0]+[0-9]*$/gi, "")
let disabledMin, disabledMax
if (this.checkIsMinNum(num)) { //輸入的數(shù)量 小于最小的數(shù),則輸入框顯示最小值
num = this.data.minNum
disabledMin = true
disabledMax = false
} else if (this.checkIsMaxNum(num)) { //輸入的數(shù)量 大于最大的數(shù)哥力,則輸入框顯示最大值
this.data.disabledMax = true
num = this.data.maxNum
disabledMin = false
disabledMax = true
} else { //輸入的數(shù)量 大于最小的數(shù)蔗怠,則輸入框顯示輸入值
disabledMin = false
disabledMax = false
}
this.setData({
num: num,
disabledMin: disabledMin,
disabledMax: disabledMax
})
this.triggerEvent('optionNum', { num: num })
},
附自定義組件的全部代碼
1墩弯、js中的代碼
// component/optionNumber-component/optionNumber-component.js
Component({
/**
* 組件的屬性列表
*/
properties: {
minNum:{
type:Number,
value: NaN
},
maxNum:{
type:Number,
value:NaN
},
},
/**
* 組件的初始數(shù)據(jù)
*/
data: {
num: 0,
disabledMin: false,
disabledMax:false
},
lifetimes:{
// 初始化數(shù)據(jù)
attached:function(){
let num, disabledMin, disabledMax
if (this.checkIsMinNum(this.data.num)) { //小于最小數(shù)
num = this.data.minNum
disabledMin = true
disabledMax = false
} else if (this.checkIsMaxNum(this.data.num)){ //大于最大數(shù)
num = this.data.maxNum
disabledMax = true
disabledMin = false
}else {
num = this.data.num
disabledMin = false
disabledMax = false
}
this.setData({
num: num,
disabledMin: disabledMin,
disabledMax: disabledMax
})
},
},
/**
* 組件的方法列表
*/
methods: {
// 減少數(shù)量
_reduce: function (e) {
// console.log("_reduce======", this.data.maxNum)
let num, disabledMin, disabledMax
num = parseInt(this.data.num) - 1
if (this.checkIsMinNum(num)) { //小于最小數(shù)
num = this.data.minNum
disabledMin = true
disabledMax = false
}else{
disabledMin = false
disabledMax = false
}
this.setData({
num: num,
disabledMin: disabledMin,
disabledMax: disabledMax
})
// console.log("disabledMin======", this.data.disabledMin)
this.triggerEvent('optionNum',{num:num})
},
// 增加數(shù)量
_add: function (e) {
let num = parseInt(this.data.num) + 1
// console.log("_add======", this.data.maxNum)
if (this.checkIsMaxNum(num)) { //大于最大數(shù)
num = this.data.maxNum
this.data.disabledMax = true
this.data.disabledMin = false
}else {
this.data.disabledMin = false
this.data.disabledMax = false
}
this.setData({
num: num,
disabledMin: this.data.disabledMin,
disabledMax: this.data.disabledMax
})
this.triggerEvent('optionNum', { num: num })
},
// 手動(dòng)輸入數(shù)量
_input: function (e) {
let val = e.detail.value
var num = val.replace(/^[0]+[0-9]*$/gi, "")
if (this.checkIsMinNum(num)) { //小于最小數(shù)
this.data.disabledMin = true
this.data.disabledMax = false
} else if (this.checkIsMaxNum(num)) { //大于最大數(shù)
this.data.disabledMax = true
this.data.disabledMin = false
} else {
this.data.disabledMin = false
this.data.disabledMax = false
}
this.setData({
num: num,
disabledMin: this.data.disabledMin,
disabledMax:this.data.disabledMax
})
this.triggerEvent('optionNum', { num: num })
},
// 失去焦點(diǎn)
_blur:function(e){
// console.log("_confirm======")
let val = e.detail.value
let num = val.replace(/^[0]+[0-9]*$/gi, "")
let disabledMin, disabledMax
if (this.checkIsMinNum(num)) { //輸入的數(shù)量 小于最小的數(shù),則輸入框顯示最小值
num = this.data.minNum
disabledMin = true
disabledMax = false
} else if (this.checkIsMaxNum(num)) { //輸入的數(shù)量 大于最大的數(shù)寞射,則輸入框顯示最大值
this.data.disabledMax = true
num = this.data.maxNum
disabledMin = false
disabledMax = true
} else { //輸入的數(shù)量 大于最小的數(shù)渔工,則輸入框顯示輸入值
disabledMin = false
disabledMax = false
}
this.setData({
num: num,
disabledMin: disabledMin,
disabledMax: disabledMax
})
this.triggerEvent('optionNum', { num: num })
},
// 檢查是否是最大數(shù)
checkIsMaxNum: function (checkNum) {
return this.data.maxNum != "NaN" && checkNum >= this.data.maxNum
},
// 檢查是否是最小數(shù)
checkIsMinNum: function (checkNum) {
return this.data.minNum != "NaN" && checkNum <= this.data.minNum
}
}
})
2、wxml中的代碼
<view class='optionView'>
<button class="item" bindtap="_reduce" disabled="{{disabledMin}}" style="border:0;background:white" plain='true'>
<image class="imgReduce" src="{{disabledMin ? '/images/icon/ic_reduce_grey.png' : '/images/icon/ic_reduce.png'}}"></image>
</button>
<view class="space">|</view>
<view class="item">
<input class="inputNum" type='number' maxlength='3' bindinput="_input" value="{{num}}" placeholder="0" confirm-type="確認(rèn)" bindblur="_blur" placeholder-style="font-size:26rpx;color:#C81432"></input>
</view>
<view class="space">|</view>
<button class="item" bindtap="_add" disabled="{{disabledMax}}" style="margin-left:6rpx;border:0;background:white" plain='true'>
<image class="imgAdd" src="{{disabledMax ? '/images/icon/ic_add_grey.png' : '/images/icon/ic_add.png'}}"></image>
</button>
</view>
3桥温、wxss中的代碼
.optionView{
height: 58rpx;
width: 240rpx;
display: flex;
flex-direction: row;
border: 1rpx solid #999;
border-radius: 10rpx;
justify-content: space-around;
align-items: center;
align-content: center;
background: white;
margin-right: 64rpx;
}
.item{
flex: 1;
display: flex;
align-items: center;
align-content: center;
justify-content: space-around;
}
.space{
height: 40rpx;
width: 1rpx;
color: #999;
font-size: 30rpx;
}
.imgAdd{
width: 16rpx;
height: 16rpx;
padding-top: 14rpx;
padding-bottom: 14rpx
}
.imgReduce{
width: 16rpx;
height: 3.5rpx;
padding-top: 18rpx;
padding-bottom: 18rpx
}
.inputNum{
width: 70rpx;
color: #C81432;
font-size: 26rpx;
text-align: center;
padding-left: 10rpx;
padding-right: 10rpx;
}
.textMax{
margin-top: 45rpx;
margin-bottom: 36rpx;
}
4引矩、json中的代碼
{
"component": true,
"usingComponents": {}
}