Browse Source

新增短信验证码倒计时组件 my-input-code

zhontai 2 years ago
parent
commit
a7b06d03ee
2 changed files with 72 additions and 14 deletions
  1. 65 0
      src/components/my-input-code/index.vue
  2. 7 14
      src/views/admin/login/component/mobile.vue

+ 65 - 0
src/components/my-input-code/index.vue

@@ -0,0 +1,65 @@
+<template>
+  <el-input text maxlength="4" placeholder="请输入验证码" clearable autocomplete="off" v-bind="$attrs">
+    <template #prefix>
+      <el-icon class="el-input__icon"><ele-Message /></el-icon>
+    </template>
+    <template #suffix>
+      <el-link type="primary" :underline="false" v-show="state.status !== 'countdown'" :disabled="state.status === 'countdown'" @click="onClick">{{
+        state.status === 'ready' ? state.startText : state.endText
+      }}</el-link>
+      <el-countdown
+        v-show="state.status === 'countdown'"
+        :format="state.changeText"
+        :value="state.countdown"
+        value-style="font-size:var(--el-font-size-base);color:var(--el-color-primary)"
+        @change="onChange"
+      />
+    </template>
+  </el-input>
+</template>
+
+<script lang="ts" setup name="my-input-code">
+import { reactive } from 'vue'
+
+const props = defineProps({
+  seconds: {
+    type: Number,
+    default: 60,
+  },
+  startText: {
+    type: String,
+    default: '获取验证码',
+  },
+  changeText: {
+    type: String,
+    default: 's秒重新获取',
+  },
+  endText: {
+    type: String,
+    default: '重新获取',
+  },
+})
+
+const state = reactive({
+  status: 'ready',
+  startText: props.startText,
+  changeText: props.changeText,
+  endText: props.endText,
+  countdown: Date.now(),
+})
+
+const onClick = () => {
+  state.status = 'countdown'
+  state.countdown = Date.now() + (props.seconds + 1) * 1000
+}
+
+const onChange = (value: number) => {
+  if (value < 1000) state.status = 'finish'
+}
+</script>
+
+<style scoped lang="scss">
+:deep(.el-statistic__content) {
+  font-size: var(--el-font-size-base);
+}
+</style>

+ 7 - 14
src/views/admin/login/component/mobile.vue

@@ -3,34 +3,27 @@
     <el-form-item class="login-animation1">
       <el-input text :placeholder="$t('message.mobile.placeholder1')" v-model="state.ruleForm.userName" clearable autocomplete="off">
         <template #prefix>
-          <i class="iconfont icon-dianhua el-input__icon"></i>
+          <el-icon class="el-input__icon"><ele-Iphone /></el-icon>
         </template>
       </el-input>
     </el-form-item>
     <el-form-item class="login-animation2">
-      <el-col :span="15">
-        <el-input text maxlength="4" :placeholder="$t('message.mobile.placeholder2')" v-model="state.ruleForm.code" clearable autocomplete="off">
-          <template #prefix>
-            <el-icon class="el-input__icon"><ele-Position /></el-icon>
-          </template>
-        </el-input>
-      </el-col>
-      <el-col :span="1"></el-col>
-      <el-col :span="8">
-        <el-button v-waves class="login-content-code">{{ $t('message.mobile.codeText') }}</el-button>
-      </el-col>
+      <MyInputCode v-model="state.ruleForm.code"></MyInputCode>
     </el-form-item>
     <el-form-item class="login-animation3">
       <el-button round type="primary" v-waves class="login-content-submit">
         <span>{{ $t('message.mobile.btnText') }}</span>
       </el-button>
     </el-form-item>
+
     <div class="font12 mt30 login-animation4 login-msg">{{ $t('message.mobile.msgText') }}</div>
   </el-form>
 </template>
 
-<script setup lang="ts" name="loginMobile">
-import { reactive } from 'vue'
+<script lang="ts" setup name="loginMobile">
+import { reactive, defineAsyncComponent } from 'vue'
+
+const MyInputCode = defineAsyncComponent(() => import('/@/components/my-input-code/index.vue'))
 
 // 定义变量内容
 const state = reactive({