uni-number-box.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <template>
  2. <view class="uni-numbox">
  3. <view class="uni-numbox-minus"
  4. @click.stop="_calcValue('subtract')"
  5. >
  6. <text class="yticon icon--jianhao" :class="minDisabled?'uni-numbox-disabled': ''" ></text>
  7. </view>
  8. <input
  9. class="uni-numbox-value"
  10. type="number"
  11. :disabled="true"
  12. v-model="inputValue"
  13. @focus.stop="_onfocus"
  14. @blur.stop="_onBlur"
  15. @click.stop="_onClick"
  16. >
  17. <view
  18. class="uni-numbox-plus"
  19. @click.stop="_calcValue('add')"
  20. >
  21. <text class="yticon icon-jia2" :class="maxDisabled?'uni-numbox-disabled': ''" ></text>
  22. </view>
  23. <!-- {{forbid}} -->
  24. </view>
  25. </template>
  26. <script>
  27. export default {
  28. name: 'uni-number-box',
  29. props: {
  30. isMax: {
  31. type: Boolean,
  32. default: false
  33. },
  34. isMin: {
  35. type: Boolean,
  36. default: false
  37. },
  38. index: {
  39. type: Number,
  40. default: 0
  41. },
  42. forbid: {
  43. type: Number,
  44. default: 0
  45. },
  46. value: {
  47. type: Number,
  48. default: 0
  49. },
  50. min: {
  51. type: Number,
  52. default: -Infinity
  53. },
  54. max: {
  55. type: Number,
  56. default: Infinity
  57. },
  58. step: {
  59. type: Number,
  60. default: 1
  61. },
  62. disabled: {
  63. type: Boolean
  64. }
  65. },
  66. data() {
  67. return {
  68. inputValue: this.value,
  69. minDisabled: false,
  70. maxDisabled: false
  71. }
  72. },
  73. created(){
  74. this.maxDisabled = this.isMax;
  75. this.minDisabled = this.isMin;
  76. console.log(this.forbid)
  77. },
  78. computed: {
  79. },
  80. watch: {
  81. inputValue(number) {
  82. const data = {
  83. number: number,
  84. index: this.index
  85. }
  86. this.$emit('eventChange', data);
  87. },
  88. value(number){
  89. this.inputValue = number;
  90. }
  91. },
  92. methods: {
  93. _onfocus(){},
  94. _onClick(){},
  95. _calcValue(type) {
  96. if(this.forbid !== 0){
  97. uni.showToast({
  98. title:"活动商品仅能购买一件",
  99. icon:"none"
  100. })
  101. return
  102. }
  103. const scale = this._getDecimalScale();
  104. let value = this.inputValue * scale;
  105. let newValue = 0;
  106. let step = this.step * scale;
  107. if(type === 'subtract'){
  108. newValue = value - step;
  109. if (newValue <= this.min){
  110. this.minDisabled = true;
  111. }
  112. if(newValue < this.min){
  113. newValue = this.min
  114. }
  115. if(newValue < this.max && this.maxDisabled === true){
  116. this.maxDisabled = false;
  117. }
  118. }else if(type === 'add'){
  119. newValue = value + step;
  120. if (newValue >= this.max){
  121. this.maxDisabled = true;
  122. }
  123. if(newValue > this.max){
  124. newValue = this.max
  125. }
  126. if(newValue > this.min && this.minDisabled === true){
  127. this.minDisabled = false;
  128. }
  129. }
  130. if(newValue === value){
  131. return;
  132. }
  133. this.inputValue = newValue / scale;
  134. },
  135. _getDecimalScale() {
  136. let scale = 1;
  137. // 浮点型
  138. if (~~this.step !== this.step) {
  139. scale = Math.pow(10, (this.step + '').split('.')[1].length);
  140. }
  141. return scale;
  142. },
  143. _onBlur(event) {
  144. let value = event.detail.value;
  145. if (!value) {
  146. this.inputValue = 0;
  147. return
  148. }
  149. value = +value;
  150. if (value > this.max) {
  151. value = this.max;
  152. } else if (value < this.min) {
  153. value = this.min
  154. }
  155. this.inputValue = value
  156. }
  157. }
  158. }
  159. </script>
  160. <style>
  161. .uni-numbox {
  162. /* position:absolute; */
  163. /* left: 30upx; */
  164. bottom: 0;
  165. display: flex;
  166. justify-content: flex-start;
  167. align-items: center;
  168. height: 46rpx;
  169. /* width:230upx; */
  170. /* height: 70upx; */
  171. /* background:#f5f5f5; */
  172. }
  173. .uni-numbox-minus,
  174. .uni-numbox-plus {
  175. margin: 0;
  176. /* background-color: #f5f5f5; */
  177. width: 70upx;
  178. /* height: 100%; */
  179. height: 46rpx;
  180. /* padding: 0 10rpx; */
  181. /* line-height: 70upx; */
  182. text-align: center;
  183. position: relative;
  184. }
  185. .uni-numbox-minus .yticon,
  186. .uni-numbox-plus .yticon{
  187. font-size: 36upx;
  188. color: #555;
  189. }
  190. .uni-numbox-minus {
  191. border-right: none;
  192. border-top-left-radius: 22upx;
  193. border-bottom-left-radius: 22upx;
  194. border: #EEEAEA solid 2rpx;
  195. }
  196. .uni-numbox-plus {
  197. border-left: none;
  198. border-top-right-radius: 22upx;
  199. border-bottom-right-radius: 22upx;
  200. border: #EEEAEA solid 2rpx;
  201. }
  202. .uni-numbox-value {
  203. position: relative;
  204. /* background-color: #f5f5f5; */
  205. width: 90upx;
  206. color: #1B1C33;
  207. border-top: #EEEAEA solid 2rpx;
  208. border-bottom: #EEEAEA solid 2rpx;
  209. /* height: 50upx; */
  210. height: 46rpx;
  211. text-align: center;
  212. padding: 0;
  213. font-size: 32upx;
  214. line-height: 44rpx;
  215. }
  216. .uni-numbox-disabled.yticon {
  217. color: #d6d6d6;
  218. }
  219. </style>