Vue纯数字验证码

谁借莪1个温暖的怀抱¢ 2022-03-26 09:06 367阅读 0赞

该验证码为4个数字生成的验证码,亲自验证点击切换,验证码组件Identify.vue可直接复制使用

提示: 该验证码图片缩小后数字经常看不清所以在这里仅仅是实现,没有详细进行实现登陆,仅仅实现了生成验证码,点击验证码后刷新验证码,真正的项目,若验证码图片要求小一点该验证码方式不合适,所以没有进行详细设计

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTk5NjYzMg_size_16_color_FFFFFF_t_70

Identify.vue

  1. <template>
  2. <div class="s-canvas">
  3. <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'SIdentify',
  9. props: {
  10. identifyCode: {
  11. type: String,
  12. default: '1234'
  13. },
  14. fontSizeMin: {
  15. type: Number,
  16. default: 16
  17. },
  18. fontSizeMax: {
  19. type: Number,
  20. default: 40
  21. },
  22. backgroundColorMin: {
  23. type: Number,
  24. default: 180
  25. },
  26. backgroundColorMax: {
  27. type: Number,
  28. default: 240
  29. },
  30. colorMin: {
  31. type: Number,
  32. default: 50
  33. },
  34. colorMax: {
  35. type: Number,
  36. default: 160
  37. },
  38. lineColorMin: {
  39. type: Number,
  40. default: 40
  41. },
  42. lineColorMax: {
  43. type: Number,
  44. default: 180
  45. },
  46. dotColorMin: {
  47. type: Number,
  48. default: 0
  49. },
  50. dotColorMax: {
  51. type: Number,
  52. default: 255
  53. },
  54. contentWidth: {
  55. type: Number,
  56. default: 112
  57. },
  58. contentHeight: {
  59. type: Number,
  60. default: 38
  61. }
  62. },
  63. methods: {
  64. // 生成一个随机数
  65. randomNum (min, max) {
  66. return Math.floor(Math.random() * (max - min) + min)
  67. },
  68. // 生成一个随机的颜色
  69. randomColor (min, max) {
  70. var r = this.randomNum(min, max)
  71. var g = this.randomNum(min, max)
  72. var b = this.randomNum(min, max)
  73. return 'rgb(' + r + ',' + g + ',' + b + ')'
  74. },
  75. drawPic () {
  76. var canvas = document.getElementById('s-canvas')
  77. var ctx = canvas.getContext('2d')
  78. ctx.textBaseline = 'bottom'
  79. // 绘制背景
  80. ctx.fillStyle = this.randomColor(
  81. this.backgroundColorMin,
  82. this.backgroundColorMax
  83. )
  84. ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
  85. // 绘制文字
  86. for (let i = 0; i < this.identifyCode.length; i++) {
  87. this.drawText(ctx, this.identifyCode[i], i)
  88. }
  89. this.drawLine(ctx)
  90. this.drawDot(ctx)
  91. },
  92. drawText (ctx, txt, i) {
  93. ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
  94. ctx.font =
  95. this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei'
  96. var x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1))
  97. var y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
  98. var deg = this.randomNum(-45, 45)
  99. // 修改坐标原点和旋转角度
  100. ctx.translate(x, y)
  101. ctx.rotate(deg * Math.PI / 180)
  102. ctx.fillText(txt, 0, 0)
  103. // 恢复坐标原点和旋转角度
  104. ctx.rotate(-deg * Math.PI / 180)
  105. ctx.translate(-x, -y)
  106. },
  107. drawLine (ctx) {
  108. // 绘制干扰线
  109. for (let i = 0; i < 8; i++) {
  110. ctx.strokeStyle = this.randomColor(
  111. this.lineColorMin,
  112. this.lineColorMax
  113. )
  114. ctx.beginPath()
  115. ctx.moveTo(
  116. this.randomNum(0, this.contentWidth),
  117. this.randomNum(0, this.contentHeight)
  118. )
  119. ctx.lineTo(
  120. this.randomNum(0, this.contentWidth),
  121. this.randomNum(0, this.contentHeight)
  122. )
  123. ctx.stroke()
  124. }
  125. },
  126. drawDot (ctx) {
  127. // 绘制干扰点
  128. for (let i = 0; i < 100; i++) {
  129. ctx.fillStyle = this.randomColor(0, 255)
  130. ctx.beginPath()
  131. ctx.arc(
  132. this.randomNum(0, this.contentWidth),
  133. this.randomNum(0, this.contentHeight),
  134. 1,
  135. 0,
  136. 2 * Math.PI
  137. )
  138. ctx.fill()
  139. }
  140. }
  141. },
  142. watch: {
  143. identifyCode () {
  144. this.drawPic()
  145. }
  146. },
  147. mounted () {
  148. this.drawPic()
  149. }
  150. }
  151. </script>
  152. <style scoped>
  153. </style>

Login.vue 一下是引用,注意位置

首先是引入验证码组件

  1. import Identify from '@/utils/Identify'
  2. export default {
  3. components: {
  4. Identify
  5. }
  6. }

在表单中引入

  1. <Row>
  2. <Col span="24">
  3. <FormItem prop="yzm">
  4. <Input type="text" v-model="yzm" placeholder="yzm" />
  5. <div @click="refreshCode">
  6. <Identify :identifyCode="identifyCode"></Identify>
  7. </div>
  8. </FormItem>
  9. </Col>
  10. </Row>

点击触发事件,在方法method中

  1. // 生成随机数
  2. randomNum (min, max) {
  3. return Math.floor(Math.random() * (max - min) + min)
  4. },
  5. // 切换验证码
  6. refreshCode () {
  7. this.identifyCode = ''
  8. this.makeCode(this.identifyCodes, 4)
  9. },
  10. // 生成四位随机验证码
  11. makeCode (o, l) {
  12. for (let i = 0; i < l; i++) {
  13. this.identifyCode += this.identifyCodes[
  14. this.randomNum(0, this.identifyCodes.length)
  15. ]
  16. }
  17. console.log(this.identifyCode)
  18. }

页面首次进入必须将默认的验证码去掉,并刷出新的验证码

  1. mounted () {
  2. this.identifyCode = ''
  3. this.makeCode(this.identifyCodes, 4)
  4. },

Login.vue登录页全页代码

  1. <template>
  2. <div>
  3. <public-header></public-header>
  4. <hr/>
  5. <Form ref="login" :model="user" :rules="ruleInline" inline>
  6. <Row>
  7. <Col span="24">
  8. <FormItem prop="account">
  9. <Input type="text" v-model="user.account" placeholder="Account">
  10. <Icon type="ios-person-outline" slot="prepend"></Icon>
  11. </Input>
  12. </FormItem>
  13. </Col>
  14. </Row>
  15. <Row>
  16. <Col span="24">
  17. <FormItem prop="password">
  18. <Input type="password" v-model="user.password" placeholder="Password">
  19. <Icon type="ios-lock-outline" slot="prepend"></Icon>
  20. </Input>
  21. </FormItem>
  22. </Col>
  23. </Row>
  24. <Row>
  25. <Col span="24">
  26. <FormItem prop="yzm">
  27. <Input type="text" v-model="yzm" placeholder="yzm" />
  28. <div @click="refreshCode">
  29. <Identify :identifyCode="identifyCode"></Identify>
  30. </div>
  31. </FormItem>
  32. </Col>
  33. </Row>
  34. <Row>
  35. <Col span="24">
  36. <FormItem>
  37. <Button type="primary" @click="handleSubmit('login')">登陆</Button>
  38. <Button type="primary" @click="back">去首页</Button>
  39. </FormItem>
  40. </Col>
  41. </Row>
  42. </Form>
  43. <hr/>
  44. <public-footer></public-footer>
  45. </div>
  46. </template>
  47. <script>
  48. import PublicFooter from '@/views/background/publicpages/PublicFooter'
  49. import PublicHeader from '@/views/background/publicpages/PublicHeader'
  50. import Identify from '@/utils/Identify'
  51. import {
  52. login
  53. } from '@/services/login'
  54. export default {
  55. name: 'Login',
  56. components: {
  57. PublicFooter,
  58. PublicHeader,
  59. Identify
  60. },
  61. data () {
  62. return {
  63. msg: '这个是登录页',
  64. identifyCodes: '1234567890',
  65. identifyCode: '',
  66. user: {
  67. account: '',
  68. password: '',
  69. verifycode: ''
  70. },
  71. ruleInline: {
  72. account: [{
  73. required: true,
  74. message: 'Please fill in the account',
  75. trigger: 'blur'
  76. }, {
  77. type: 'string',
  78. min: 5,
  79. message: 'The account length cannot be less than 5 bits',
  80. trigger: 'blur'
  81. }],
  82. password: [{
  83. required: true,
  84. message: 'Please fill in the password.',
  85. trigger: 'blur'
  86. }, {
  87. type: 'string',
  88. min: 6,
  89. message: 'The password length cannot be less than 6 bits',
  90. trigger: 'blur'
  91. }],
  92. yzm: [{
  93. required: true,
  94. message: 'Please fill in the yzm.',
  95. trigger: 'blur'
  96. }, {
  97. type: 'string',
  98. min: 4,
  99. message: 'The yzm length cannot be less than 4 bits',
  100. trigger: 'blur'
  101. }]
  102. }
  103. }
  104. },
  105. mounted () {
  106. this.identifyCode = ''
  107. this.makeCode(this.identifyCodes, 4)
  108. },
  109. methods: {
  110. handleSubmit (name) {
  111. this.$refs[name].validate((valid) => {
  112. if (valid) {
  113. // 配置默认接口地址,封装参数发送,以下注释中的请求也可以
  114. /* const para = Object.assign({}, this.user)
  115. setTimeout(() => {
  116. login(para).then(res => {
  117. }).catch(() => {
  118. // 登陆失败操作
  119. }, 500)
  120. }) */
  121. // 带参发送
  122. setTimeout(() => {
  123. login({
  124. account: this.user.account,
  125. password: this.user.password
  126. }).then(res => {
  127. }).catch(() => {
  128. // 登陆失败操作
  129. }, 500)
  130. })
  131. } else {
  132. console.log('error submit!!')
  133. return false
  134. }
  135. })
  136. },
  137. back () {
  138. this.$router.push('/')
  139. },
  140. // 生成随机数
  141. randomNum (min, max) {
  142. return Math.floor(Math.random() * (max - min) + min)
  143. },
  144. // 切换验证码
  145. refreshCode () {
  146. this.identifyCode = ''
  147. this.makeCode(this.identifyCodes, 4)
  148. },
  149. // 生成四位随机验证码
  150. makeCode (o, l) {
  151. for (let i = 0; i < l; i++) {
  152. this.identifyCode += this.identifyCodes[
  153. this.randomNum(0, this.identifyCodes.length)
  154. ]
  155. }
  156. console.log(this.identifyCode)
  157. }
  158. }
  159. }
  160. </script>
  161. <style lang="postcss" scoped>
  162. body {
  163. background-color: #ff0000;
  164. }
  165. </style>

代码生成效果

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTk5NjYzMg_size_16_color_FFFFFF_t_70 1

发表评论

表情:
评论列表 (有 0 条评论,367人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Vue实现验证

    在Web应用程序中,为了避免机器自动化或恶意攻击,很常见的做法是要求用户在表单提交之前输入验证码。验证码最常见的形式是图片验证码,因为图片验证码最大程度地防止了自动化机器调用A