这样一个简单的组件,翻了ant.design才知道这种组件叫做步进器(steper),步进器常用于购物车等需要增减数量的场景,最近的旅游项目中用于增减房间数和人数,从产品的角度来理解步进器很简单,但在开发角度来说需要适应多种场景及控制一些状态
- 边界值(最大值,最小值),初始值,步进值(一次增减数量)需要可控
- 边界状态,即超出后显示为什么状态
- 可供外部设置边界状态的api方法
- 内部加减方法
- 可供外部调用的加减方法(一些场景中,外部有一个总量约束,比如sku场景)
- 加减回调方法,比如当数量超出时提示用户相关信息
- 多实例模式,实例之间即隔离又能交互
大致需求如上,demo及实现部分如下
GITHUB源码
小程序代码片段
wxml
<view class="container">
<ui-item item="{{steperConfig}}" />
</view>
Page
因为是直接使用Item组件实现,所以组件写在Page页面中,当然独立成组件看需求了
const Pager = require('../components/aotoo/core/index')
let lib = Pager.lib
function mkSteper(id=lib.suid('step_'), min, max, step=1) {
return {
$$id: id,
itemClass: 'steper-class',
title: [
{title: '-', aim: 'reduce', itemClass: 'steper-reduce'},
{title: '0', aim: 'custom', itemClass: 'steper-counter'},
{title: '+', aim: 'plus', itemClass: 'steper-plus'},
],
methods: {
__ready(){
this.count = 0
this.min = min||0
this.max = max||10
this.step = step||1
this.stat = {
reduce: true,
plus: true,
count: true
}
},
reduce(e, param, inst){
let step = this.step
if (!inst) {
inst = this.children[0]
}
if (e === false) {
this.stat.reduce = false
inst.addClass('disable')
}
if (e === true) {
this.stat.reduce = true
inst.removeClass('disable')
}
if (typeof e === 'number') {
step = e
}
this.count -= step
if (this.count <= this.min) {
this.count = this.min
this.stat.reduce = false
inst.addClass('disable')
}
if (this.count < this.max && !this.stat.plus) {
this.stat.plus = true
let $plus = inst.siblings('steper-plus')
$plus.removeClass('disable')
}
this.changeNum(inst)
this.hooks.emit('reduce', {count: this.count}, this)
},
plus(e, param, inst){
let step = this.step
if (!inst) {
inst = this.children[2]
}
if (e === false) {
this.stat.plus = false
inst.addClass('disable')
}
if (e === true) {
this.stat.plus = true
inst.removeClass('disable')
}
if (typeof e === 'number') {
step = e
}
this.count += step
if (this.count >= this.max) {
this.count = this.max
this.stat.plus = false
inst.addClass('disable')
}
if (this.count > this.min && !this.stat.reduce) {
this.stat.reduce = true
let $reduce = inst.siblings('steper-reduce')
$reduce.removeClass('disable')
}
this.changeNum(inst)
this.hooks.emit('plus', {count: this.count}, this)
},
changeNum(inst){
let count = this.count
if (typeof inst === 'number') {
count = inst
inst = undefined
}
if (!inst) {
inst = this.children[1]
}
let $counter = inst.siblings('steper-counter')
$counter.update({
title: count
})
}
}
}
}
Pager({
data: {
steperConfig: mkSteper('steper'),
},
onReady(){
let $steper = this.getElementsById('steper')
$steper.hooks.on('plus', function(param) {
if (this.count === 10) {
Pager.alert('不能再多了,仓库没货了')
}
})
$steper.hooks.on('reduce', function(param) {
if (param.count <= 0) {
Pager.alert('大哥,买点啊')
}
})
}
})
over了
可以,我到时候也写篇文章