canvas验证码 uni-app/小程序

  1 <template>
  2     <view class="logo-wrapper">
  3         <view class="logo-img">
  4             <image src="../../static/images/logo-login.png" mode="widthFix" />
  5         </view>
  6         <view class="form-box">
  7             <view class="form-item">
  8                 <view class="icon-box">
  9                     <i class="iconfont icon-yonghu"></i>
 10                 </view>
 11                 <input class="ipt" v-model="username" type="text" placeholder="用户名" />
 12             </view>
 13             <view class="form-item">
 14                 <view class="icon-box">
 15                     <i class="iconfont icon-mima"></i>
 16                 </view>
 17                 <input class="ipt" v-model="password" type="password" placeholder="密码" />
 18             </view>
 19             <view class="form-item">
 20                 <view class="icon-box">
 21                     <i class="iconfont icon-yanzhengma"></i>
 22                 </view>
 23                 <input class="ipt short" v-model="capCode" type="text" placeholder="验证码" />
 24                 <canvas class="canvas" canvas-id="yzmCanvas" id="yzmCanvas" @tap="tapCaptcha"></canvas>
 25             </view>
 26             <button class="btn-login" @tap="login">登录</button>
 27         </view>
 28         <view class="bottom-img">
 29             <image src="../../static/images/login-bottom.png" mode="widthFix" />
 30         </view>
 31     </view>
 32 </template>
 33 
 34 <script>
 35     export default {
 36         data() {
 37             return {
 38                 capShow: true,
 39                 username: '',
 40                 password: '',
 41                 capCode: '',
 42                 uuid: ''
 43             }
 44         },
 45         methods: {
 46             async queryCaptcha() {
 47                 const { data } = await this.$http({
 48                     url: '/captchaImage',
 49                     method: 'GET',
 50                 });
 51                 this.uuid = data.data.uuid;
 52                 this.creatCanvas(data.data.image);
 53             },
 54             tapCaptcha() {
 55                 this.capShow = false;
 56                 this.$nextTick(() => {
 57                     this.capShow = true;
 58                     this.queryCaptcha();
 59                 });
 60             },
 61             //得到随机的颜色值
 62             randomColor() {
 63                 var r = Math.floor(Math.random() * 256);
 64                 var g = Math.floor(Math.random() * 256);
 65                 var b = Math.floor(Math.random() * 256);    
 66                 return 'rgb(' + r + ',' + g + ',' + b + ')';
 67             },
 68             creatCanvas(str) {
 69                 const ctx = uni.createCanvasContext('yzmCanvas');
 70                 ctx.setFontSize(28 + Math.floor(Math.random() * 4 - 2));
 71                 ctx.setFillStyle(this.randomColor());
 72                 for (let i = 0; i < 4; i++) {
 73                     ctx.setFontSize(28 + Math.floor(Math.random() * 4 - 2));
 74                     ctx.fillText(str[i], 20 * i + 10, 32);
 75                     ctx.setFillStyle(this.randomColor());
 76                     // 旋转随机在-3到3之间
 77                     ctx.rotate((Math.floor(Math.random() * 6 - 3) * Math.PI) / 180);
 78                 }
 79                 // 直线 begin path
 80                 for (let i = 0; i < 4; i++) {
 81                     ctx.beginPath();
 82                     ctx.setStrokeStyle(this.randomColor());
 83                     // x/-10~110 y/-10~50
 84                     ctx.moveTo(
 85                       Math.floor(Math.random() * 100) + Math.floor(Math.random() * 20 - 10),
 86                       Math.floor(Math.random() * 40) + Math.floor(Math.random() * 20 - 10)
 87                     );
 88                     ctx.lineTo(
 89                       Math.floor(Math.random() * 100) + Math.floor(Math.random() * 20 - 10),
 90                       Math.floor(Math.random() * 40) + Math.floor(Math.random() * 20 - 10)
 91                     );
 92                     ctx.stroke();
 93                  }
 94                 ctx.draw();
 95             },
 96             async login() {
 97                 if(this.username === '') {
 98                     uni.showToast({
 99                         icon: 'none',
100                         title: '请填写用户名'
101                     });
102                     return;
103                 }
104                 if(this.password === '') {
105                     uni.showToast({
106                         icon: 'none',
107                         title: '请填写密码'
108                     });
109                     return;
110                 }
111                 if(this.capCode === '') {
112                     uni.showToast({
113                         icon: 'none',
114                         title: '请填写验证码'
115                     });
116                     return;
117                 }
118                 const { data } = await this.$http({
119                     url: '/login',
120                     method: 'POST',
121                     data: {
122                         username: this.username,
123                         password: this.password,
124                         code: this.capCode,
125                         uuid: this.uuid
126                     }
127                 });
128                 uni.setStorageSync('token', data.data.token);
129                 
130                 const res = await this.$http({
131                     url: '/personal/userInfo',
132                     method: 'GET',
133                     data: {
134                         token: data.data.token,
135                     }
136                 });
137                 let userInfo = res.data.data;
138                 uni.setStorageSync('userInfo', userInfo);
139                 
140                 uni.switchTab({
141                     url: '/pages/index/index'
142                 });
143             }
144         },
145         onLoad() {
146             this.queryCaptcha();
147         },
148     }
149 </script>
150 
151 <style lang="scss">
152 .logo-wrapper {
153     display: flex;
154     flex-direction: column;
155     align-items: center;
156     justify-content: space-between;
157 }
158 .logo-img {
159      590upx;
160     height: 246upx;
161     margin-top: 60upx;
162 }
163 .form-box {
164      560upx;
165     height: 580upx;
166     margin: 30upx 0 140upx 0;
167 }
168 .form-item {
169      100%;
170     height: 82upx;
171     margin-top: 48upx;
172     border-bottom: 1px solid #c1c1c1;
173     display: flex;
174     align-items: center;
175 }
176 .icon-box {
177      50upx;
178     height: 50upx;
179     border-radius: 50%;
180     margin-right: 40upx;
181     text-align: center;
182     line-height: 42upx;
183     background-color: #f0443c;
184     color: #fff;
185     i {
186         font-size: 24upx;
187     }
188 }
189 .ipt {
190     flex: 1;
191     height: 80upx;
192 }
193 .canvas {
194      190upx; 
195     height: 68upx;
196     border: 1px solid #f1f1f1;
197     background: #fdfdfd;
198 }
199 .btn-login {
200     margin-top: 84upx;
201     background-color: #f0443c;
202     color: #fff;
203 }
204 .bottom-img {
205      628upx;
206     height: 124upx;
207     // margin: 50upx auto 0;
208 }
209 </style>
原文地址:https://www.cnblogs.com/guwufeiyang/p/14898838.html