xquery实现的小程序步进器
发布于 5 年前 作者 lihou 3803 次浏览 来自 分享

这样一个简单的组件,翻了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了

1 回复

可以,我到时候也写篇文章

回到顶部