这一段时间做小程序项目,使用的是mpvue的框架,需要自己实现验证码输入,模拟input的光标,上一个框输入后后一个框自动获取焦点,删除时从后往前依次删除。下图是整体效果:

  1 <template> 
  2   <div class="validate-code"> 
  3     <h3>验证码已发送至</h3> 
  4     <div class="middle"> 
  5       <div class="tel">{{telPhone}}</div> 
  6       <div class="right"> 
  7         <div class="timer" v-if="timer">({{count}}s)</div> 
  8         <div class="txt-btn" v-else @click="getCode">重新获取验证码</div> 
  9       </div> 
 10     </div> 
 11     <div class="code-wrap"> 
 12       <input type="number" 
 13              placeholder="输入短信验证码" 
 14              :maxlength="6" 
 15              placeholder-style="color: #ccc;" 
 16              @focus="handleFocus" 
 17              @blur="handleBlur" 
 18              v-model="validateCode"> 
 19       <div class="front-wrap" @click="getFocus"> 
 20         <div class="block"> 
 21           <i :class="{'active': validateCode.length === 0 && hasFocused}"></i> 
 22           {{validateArray[0]}} 
 23         </div> 
 24         <div class="block"> 
 25           <i :class="{'active': validateCode.length === 1 && hasFocused}"></i> 
 26           {{validateArray[1]}} 
 27         </div> 
 28         <div class="block"> 
 29           <i :class="{'active': validateCode.length === 2 && hasFocused}"></i> 
 30           {{validateArray[2]}} 
 31         </div> 
 32         <div class="block"> 
 33           <i :class="{'active': validateCode.length === 3 && hasFocused}"></i> 
 34           {{validateArray[3]}} 
 35         </div> 
 36         <div class="block"> 
 37           <i :class="{'active': validateCode.length === 4 && hasFocused}"></i> 
 38           {{validateArray[4]}} 
 39         </div> 
 40         <div class="block"> 
 41           <i :class="{'active': validateCode.length === 5 && hasFocused}"></i> 
 42           {{validateArray[5]}} 
 43         </div> 
 44       </div> 
 45       <div class="tips" v-if="errMsg">{{errMsg}}</div> 
 46     </div> 
 47     <div class="btn" :class="{'effective': validateCode.length === 6}" @click="bindPhone">登录</div> 
 48   </div> 
 49 </template> 
 50  
 51 <script> 
 52   import fly from '@/http/config' 
 53  
 54   export default { 
 55     components: {}, 
 56     data () { 
 57       return { 
 58         telPhone: '', 
 59         validateCode: '', 
 60         errMsg: '', 
 61         count: 60, 
 62         timer: null, 
 63         hasFocused: false 
 64       } 
 65     }, 
 66     computed: { 
 67       validateArray () { 
 68         return Array.from(this.validateCode); 
 69       } 
 70     }, 
 71     onShow () { 
 72       this.errMsg = ''; 
 73       this.validateCode = ''; 
 74     }, 
 75     onReady () { 
 76       this.telPhone = this.$root.$mp.query.telPhone; 
 77       this.initTimer(); 
 78     }, 
 79     created () { 
 80       // 
 81     }, 
 82     methods: { 
 83       handleFocus () { 
 84         this.hasFocused = true; 
 85         this.errMsg = ''; 
 86       }, 
 87       handleBlur() { 
 88         this.hasFocused = false; 
 89       }, 
 90  
 91       getCode () { 
 92         if (!this.timer) { 
 93           this.getBindingVerifyCode() 
 94         } 
 95       }, 
 96       getBindingVerifyCode () { 
 97         let _this = this 
 98         fly.get('/2c/*********/*******', { 
 99           phoneNum: this.telPhone 
100         }).then((data) => { 
101           wx.showToast({ 
102             title: data.message 
103           }) 
104           _this.initTimer() 
105         }, err => { 
106           console.log(err) 
107         }) 
108       }, 
109       bindPhone () { 
110         let _this = this; 
111         if (this.validateArray.length < 6) { 
112           return 
113         } 
114         fly.get('/2c/*****/*******', { 
115           phoneNum: this.telPhone, 
116           verifyCode: this.validateCode 
117         }).then((data) => { 
118           wx.showToast({ 
119             title: data.message 
120           }) 
121           wx.setStorage({ 
122             key: 'phoneNum', 
123             data: _this.telPhone 
124           }); 
125           setTimeout(() => { 
126             wx.reLaunch({ 
127               url: '/pages/index/main' 
128             }); 
129           }, 1000); 
130         }, err => { 
131           console.log(err); 
132           _this.errMsg = err.message; 
133           wx.showToast({ 
134             icon: 'none', 
135             title: err.message 
136           }); 
137         }) 
138       }, 
139       initTimer () { 
140         let _this = this 
141         this.timer = setInterval(() => { 
142           if (_this.count <= 0) { 
143             _this.count = 60 
144             clearInterval(_this.timer) 
145             _this.timer = null 
146           } 
147           _this.$set({ 
148             'count': _this.count 
149           }) 
150           _this.count-- 
151         }, 1000) 
152       } 
153     } 
154   } 
155 </script> 
156  
157  
158 <style lang="scss" src="./index.scss"> 
159  
160 </style>

CSS文件

  1 .profile{ 
  2   width: 100%; 
  3   height: 100%; 
  4   background: #f6f6f6; 
  5   .get-user-info { 
  6     width: 200px; 
  7     height: 50px; 
  8   } 
  9   .herder{ 
 10     padding: 25px 10px; 
 11     background: #f25252; 
 12     display: flex; 
 13     justify-content: flex-start; 
 14     align-items: center; 
 15     .avatar-wrap{ 
 16       width: 60px; 
 17       height: 60px; 
 18       overflow: hidden; 
 19       border-radius: 50%; 
 20       img{ 
 21         width: 60px; 
 22         height: 60px; 
 23       } 
 24     } 
 25     .user-info{ 
 26       color: #fff; 
 27       margin-left: 10px; 
 28       display: flex; 
 29       flex-direction: column; 
 30       justify-content: center; 
 31       h5{ 
 32         font-size: 16px; 
 33         line-height: 16px; 
 34         margin-bottom: 10px; 
 35       } 
 36       p{ 
 37         text-indent: 13px; 
 38         font-size: 14px; 
 39         line-height: 14px; 
 40         background: url("../../assets/images/profile/icon_phone.png") 0 50%/9px 14px no-repeat; 
 41       } 
 42     } 
 43   } 
 44   .content{ 
 45     .main{ 
 46       margin: 10px 0; 
 47       .content-item{ 
 48         height: 50px; 
 49         padding: 0 10px; 
 50         display: flex; 
 51         background: #fff; 
 52         justify-content: space-between; 
 53         align-items: center; 
 54         border-bottom: 1px solid #f6f6f6; 
 55         .left{ 
 56           display: flex; 
 57           align-items: center; 
 58           img{ 
 59             width: 15px; 
 60             height: 15px; 
 61             margin-right: 9px; 
 62           } 
 63           .title{ 
 64             font-size: 15px; 
 65             color: #333; 
 66           } 
 67         } 
 68         .arrow{ 
 69           display: flex; 
 70           justify-content: center; 
 71           align-items: center; 
 72           .phone{ 
 73             font-size: 15px; 
 74             color: #399fda; 
 75             margin-right: 8px; 
 76           } 
 77           img{ 
 78             width: 6px; 
 79             height: 9px; 
 80           } 
 81         } 
 82       } 
 83     } 
 84     .card-wrap{ 
 85       background: #fff; 
 86       padding: 12px 10px; 
 87       .card{ 
 88         height: 50px; 
 89         border-radius: 4px; 
 90         background: #ffdc69; 
 91         display: flex; 
 92         justify-content: space-between; 
 93         align-items: center; 
 94         position: relative; 
 95         .left{ 
 96           span{ 
 97             font-size: 15px; 
 98             color: #884600; 
 99             line-height: 50px; 
100           } 
101           img{ 
102             width: 34px; 
103             height: 31px; 
104             margin: 0 5px 0 10px; 
105             vertical-align: middle; 
106           } 
107         } 
108         .arrow{ 
109           display: flex; 
110           justify-content: flex-start; 
111           align-items: center; 
112           img{ 
113             width: 4px; 
114             height: 6px; 
115             margin: 0 10px 0 3px; 
116           } 
117           span{ 
118             font-size: 13px; 
119             color: #884600; 
120           } 
121         } 
122         .icon-fixed{ 
123           position: absolute; 
124           top: 0; 
125           right: 0; 
126           width: 27px; 
127           height: 27px; 
128         } 
129       } 
130     } 
131   } 
132 }


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

原生开发小程序 和 wepy 、 mpvue 对比知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。