vcode-input.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <template>
  2. <view class="vcode-input-body">
  3. <text class="vcode-input-item"
  4. :class="isBorderLine?'vcode-input-line':'vcode-input-border'"
  5. v-for="(v,index) in sum"
  6. :key="index"
  7. @tap.stop="setFocus"
  8. :style="{
  9. borderColor:text.length===index&&focus?borderActiveColor:(text.length>index?borderValueColor:borderColor),
  10. color:text.length>index?borderValueColor:borderColor
  11. }"
  12. >{{text[index]}}</text>
  13. <text class="vcode-input-item" @click="addNum" v-if="addShow">+</text>
  14. <view class="hidden-input">
  15. <input
  16. id="vcodeInput"
  17. ref="vcodeInput"
  18. type="text"
  19. :show-confirm-bar="false"
  20. auto-blur
  21. :focus="focus"
  22. :maxlength.sync="sum"
  23. v-model="value"
  24. @blur="setBlur"
  25. @focus="setFocus"
  26. :password="isPassword"
  27. placeholder="验证码"/>
  28. </view>
  29. </view>
  30. </template>
  31. <script>
  32. export default {
  33. name:'VcodeInput',
  34. props: {
  35. autofocus:{
  36. type: Boolean,
  37. default: true
  38. },
  39. sum:{
  40. type: Number,
  41. default: 6
  42. },
  43. isBorderLine:{
  44. type:Boolean,
  45. default:false
  46. },
  47. borderColor:{
  48. type:String,
  49. default:'#DADADA'
  50. },
  51. borderValueColor:{
  52. type:String,
  53. default:'#424456'
  54. },
  55. borderActiveColor:{
  56. type:String,
  57. default:'#FF6B00'
  58. },
  59. isAutoComplete:{
  60. type: Boolean,
  61. default: true
  62. },
  63. isPassword:{
  64. type: Boolean,
  65. default: false
  66. },
  67. plateNumber:{
  68. type: String,
  69. default: '0'
  70. }
  71. },
  72. data() {
  73. return {
  74. focus:false,
  75. text:[],
  76. value:'',
  77. addShow:true,
  78. };
  79. },
  80. watch:{
  81. value(value,oldVal){
  82. if(this.isAutoComplete){
  83. if(value.length>=this.sum){
  84. this.focus=false;
  85. //this.$emit('vcodeInput', value);
  86. }
  87. if(value.length>=this.sum-1){
  88. this.$emit('vcodeInput', value);
  89. }
  90. }else{
  91. this.$emit('vcodeInput', value);
  92. }
  93. if(this.isPassword){
  94. let val='';
  95. for (let i = 0; i < value.length; i++) {
  96. val+='●';
  97. }
  98. this.text=val;
  99. }else{
  100. //console.log(value)
  101. this.text=value.split("");
  102. //console.log(this.text)
  103. }
  104. },
  105. plateNumber:{
  106. immediate: true, // 很重要!!!
  107. handler (val) {
  108. console.log(val.length)
  109. var length=val.length;
  110. if(length == 7||length == 0){
  111. this.addShow=true;
  112. console.log(this.addShow)
  113. this.$emit('setsum',7)
  114. }else{
  115. this.addShow=false;
  116. this.$emit('setsum',8)
  117. }
  118. this.value=val;
  119. this.text=val.split("");
  120. }
  121. }
  122. },
  123. mounted() {
  124. this.$nextTick(() => {
  125. this.initInput()
  126. })
  127. },
  128. methods:{
  129. addNum(){
  130. //触发一个更新事件
  131. this.$emit('setsum',8)
  132. this.addShow=false;
  133. },
  134. initInput(){
  135. if(this.autofocus)
  136. this.focus=true;
  137. // #ifdef H5
  138. this.$refs.vcodeInput.$refs.input.setAttribute('type','number');
  139. this.$refs.vcodeInput.$refs.input.setAttribute('pattern','[0-9]*')
  140. // #endif
  141. },
  142. setBlur(){
  143. uni.hideKeyboard();
  144. this.$nextTick(() => {
  145. this.focus=false;
  146. })
  147. },
  148. setFocus(){
  149. this.focus=true;
  150. },
  151. clearValue(){
  152. this.setBlur();
  153. this.value='';
  154. this.text=[];
  155. this.$forceUpdate();
  156. }
  157. }
  158. }
  159. </script>
  160. <style lang="scss" scoped>
  161. .vcode-input-body{
  162. margin-left: -36rpx;
  163. margin-right: -36rpx;
  164. position: relative;
  165. overflow: hidden;
  166. /* #ifndef APP-NVUE */
  167. display: flex;
  168. /* #endif */
  169. flex-direction: row;
  170. justify-content: center;
  171. align-items: center;
  172. }
  173. .vcode-input-item{
  174. width: 60rpx;
  175. height: 60rpx;
  176. margin-left: 12rpx;
  177. margin-right: 12rpx;
  178. line-height: 60rpx;
  179. text-align: center;
  180. font-weight: 500;
  181. }
  182. .vcode-input-border{
  183. border-style: solid;
  184. border-width: 2rpx;
  185. border-color: $uni-border-color;
  186. border-radius: 4rpx;
  187. }
  188. .vcode-input-line{
  189. border-bottom-style: solid;
  190. border-bottom-width: 2rpx;
  191. border-color: $uni-border-color;
  192. }
  193. .hidden-input{
  194. width: 1px;
  195. height: 1px;
  196. position: absolute;
  197. left: -1px;
  198. top: -1px;
  199. overflow: hidden;
  200. }
  201. </style>