lxc-count.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <template>
  2. <view class="count-box" :class="status ? 'count-box-light' : 'count-box-gray'">
  3. <view class="count-less count-pub" :class="[myValue <= min ? 'light' : 'gray']" @tap.stop="less" @longpress='longpressLess' @touchend="handletouchend">-</view>
  4. <view class="count-add count-pub" :class="[myValue >= max ? 'light' : 'gray']" @tap.stop="add" @longpress='longpressAdd' @touchend="handletouchend">+</view>
  5. <input type="number" v-model="myValue" @focus="onFocus" @blur="onBlue" class="count-input"/>
  6. </view>
  7. </template>
  8. <script>
  9. export default {
  10. data(){
  11. return{
  12. myValue: 0,
  13. status: false,
  14. timer: null
  15. }
  16. },
  17. props: {
  18. // 计数器中的值
  19. value: {
  20. type: Number,
  21. default: 0
  22. },
  23. max: {
  24. type: Number,
  25. default: 10000
  26. },
  27. min: {
  28. type: Number,
  29. default: 2
  30. },
  31. // 点击当前数据的索引
  32. index: {
  33. type: Number
  34. },
  35. delayed: {
  36. type: Number,
  37. default: 200
  38. }
  39. },
  40. created() {
  41. this.myValue = this.value
  42. },
  43. watch:{
  44. value(val) {
  45. this.myValue = val
  46. }
  47. },
  48. methods: {
  49. onBlue() {
  50. if(+this.myValue >= this.max) {
  51. this.myValue = this.max
  52. this.status = false
  53. }else if(+this.myValue <= this.min) {
  54. this.myValue = this.min
  55. this.status = false
  56. }else {
  57. this.status = true
  58. this.myValue = +this.myValue
  59. }
  60. if(!isNaN(this.myValue)) {
  61. this.$emit('handleCount', this.myValue, this.index)
  62. }else {
  63. this.$emit('handleCount', 0, this.index)
  64. }
  65. },
  66. onFocus() {
  67. this.status = true
  68. },
  69. add() {
  70. this.addPublick()
  71. },
  72. addPublick() {
  73. if(this.myValue >= this.max) {
  74. this.status = false
  75. this.myValue = this.max
  76. clearInterval(this.timer)
  77. }else {
  78. this.status = true
  79. this.myValue ++
  80. }
  81. this.$emit('handleCount', this.myValue, this.index)
  82. },
  83. longpressAdd() {
  84. this.timer = setInterval(() => {
  85. this.addPublick()
  86. }, this.delayed)
  87. },
  88. less() {
  89. this.lessPublick()
  90. },
  91. lessPublick() {
  92. if(this.myValue <= this.min) {
  93. clearInterval(this.timer)
  94. this.status = false
  95. this.myValue = this.min
  96. }else {
  97. this.status = true
  98. this.myValue --
  99. }
  100. this.$emit('handleCount', this.myValue, this.index)
  101. },
  102. longpressLess() {
  103. this.timer = setInterval(() => {
  104. this.lessPublick()
  105. }, this.delayed)
  106. },
  107. handletouchend() {
  108. clearInterval(this.timer)
  109. }
  110. }
  111. }
  112. </script>
  113. <style>
  114. .gray{
  115. background: #eef3f9;
  116. color: #555555;
  117. }
  118. .light{
  119. background: #f5f7fa;
  120. color: #C8C7CC;
  121. }
  122. .count-box{
  123. position: relative;
  124. width: 220rpx;
  125. height: 60rpx;
  126. border-radius: 5px;
  127. z-index: 1;
  128. transition: all .3s;
  129. }
  130. .count-box-light{
  131. border: 1px solid #add4ff;
  132. }
  133. .count-box-gray{
  134. border: 1px solid #e4e4e4;
  135. }
  136. .count-pub{
  137. position: absolute;
  138. top: 50%;
  139. transform: translate(0, -50%);
  140. width: 60rpx;
  141. height: 100%;
  142. text-align: center;
  143. font-size: 20px;
  144. }
  145. .count-less{
  146. left: 0;
  147. border-top-left-radius:4px;
  148. border-bottom-left-radius:4px;
  149. }
  150. .count-add{
  151. right: 0;
  152. border-top-right-radius:4px;
  153. border-bottom-right-radius:4px;
  154. }
  155. .count-input{
  156. width: 110rpx;
  157. height: 100%;
  158. position: absolute;
  159. top: 0;
  160. left: 50%;
  161. transform: translate(-50%, 0);
  162. padding: 6rpx 10rpx;
  163. box-sizing: border-box;
  164. color: #808080;
  165. font-size: 26rpx;
  166. text-align: center;
  167. }
  168. </style>