custom-counter.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <template>
  2. <view class="custom-counter">
  3. <text class="reduce cuIcon-move" :class="{ disabled: inputValue == 0 }" @tap.stop="reduce"></text>
  4. <input class="num" type="number" @focus="focus" @blur="blur" maxlength="3" v-model="inputValue" />
  5. <text class="add cuIcon-add" :class="{ disabled: inputValue == max }" @tap.stop="add"></text>
  6. </view>
  7. </template>
  8. <script>
  9. import Vue from 'vue'
  10. export default {
  11. props: {
  12. args: { // 触发 change 事件回传给父组件的参数
  13. type: Array,
  14. default: () => []
  15. },
  16. value: [String, Number],
  17. zeroWarn: String, // 当 value 为 0 时是否触发 zero 事件
  18. max: {
  19. type: Number,
  20. default: () => 999
  21. }
  22. },
  23. data() {
  24. return {
  25. inputValue: this.value
  26. }
  27. },
  28. watch: {
  29. value(n) {
  30. this.inputValue = n
  31. },
  32. inputValue(n) {
  33. if (+this.inputValue > this.max) {
  34. setTimeout(() => this.inputValue = this.max)
  35. } else {
  36. this.inputValue = +this.inputValue
  37. if (this.zeroWarn) {
  38. if (this.inputValue) {
  39. this.emitInputChange()
  40. } else {
  41. let eventBUS = new Vue()
  42. this.$emit('zero', eventBUS, ...this.args)
  43. eventBUS.$on('beZero', () => {
  44. this.inputValue = 0
  45. this.emitInputChange()
  46. eventBUS = null
  47. })
  48. eventBUS.$on('beOne', () => {
  49. this.inputValue = 1
  50. this.emitInputChange()
  51. eventBUS = null
  52. })
  53. }
  54. } else {
  55. this.emitInputChange()
  56. }
  57. }
  58. }
  59. },
  60. methods: {
  61. focus() {
  62. if(this.inputValue === '0') {
  63. this.inputValue = ''
  64. }
  65. },
  66. blur() {
  67. if(this.inputValue === '') {
  68. this.inputValue = '0'
  69. }
  70. },
  71. add () { // +
  72. this.inputValue = this.value
  73. if (+this.inputValue < this.max) {
  74. this.inputValue ++
  75. } else {
  76. this.inputValue = +this.max
  77. }
  78. },
  79. reduce () { // -
  80. this.inputValue = this.value
  81. if (+this.inputValue) { // value 只允许 大于等于 0
  82. this.inputValue --
  83. }
  84. },
  85. emitInputChange() {
  86. this.$emit('input', +this.inputValue)
  87. this.$emit('change', +this.inputValue, ...this.args)
  88. }
  89. }
  90. }
  91. </script>
  92. <style lang="scss" scoped>
  93. .custom-counter {
  94. @include flex();
  95. width: 210rpx;
  96. height: 50rpx;
  97. font-size: 36rpx;
  98. border-radius:5rpx;
  99. color: $app-sec-text-color;
  100. border: 1rpx solid $app-sec-text-color;
  101. .disabled {
  102. height: 96%;
  103. background: #F5F7FA;
  104. }
  105. text, input {
  106. @include flex();
  107. flex: 1;
  108. height: 100%;
  109. box-sizing: border-box;
  110. &.num {
  111. text-align: center;
  112. color: $app-main-text-color;
  113. }
  114. &.reduce {
  115. border-right: 2rpx solid $app-sec-text-color;
  116. }
  117. &.add {
  118. border-left: 2rpx solid $app-sec-text-color;
  119. }
  120. }
  121. }
  122. </style>