phonePage.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <template>
  2. <div>
  3. <v-form @submit.prevent ref="phoneForm">
  4. <v-text-field v-model="loginData.phone" placeholder="请输入手机号" color="#00897B" variant="outlined" density="compact" :rules="phoneRules" validate-on="input">
  5. <template v-slot:prepend-inner>
  6. <span class="d-flex">
  7. <v-icon icon="mdi-cellphone" size="20"></v-icon>
  8. <span class="d-flex" id="menu-activator">
  9. <span class="phone-number">{{ currentArea }}</span>
  10. <v-icon size="20">mdi-chevron-down</v-icon>
  11. </span>
  12. <v-menu activator="#menu-activator">
  13. <v-list>
  14. <v-list-item v-for="(item, index) in items" :key="index" :value="index" @click="handleChangeCurrentArea(item)">
  15. <v-list-item-title>{{ item.label }}</v-list-item-title>
  16. </v-list-item>
  17. </v-list>
  18. </v-menu>
  19. </span>
  20. </template>
  21. </v-text-field>
  22. <v-text-field v-model="loginData.code" placeholder="请输入验证码" color="#00897B" variant="outlined" density="compact" prepend-inner-icon="mdi-security" :rules="[v=> !!v || '请填写验证码']">
  23. <template #append-inner>
  24. <span v-if="showCode" class="login-code" @click="handleCode">获取验证码</span>
  25. <span v-else class="disable">重新获取{{ count }}s</span>
  26. </template>
  27. </v-text-field>
  28. </v-form>
  29. <v-snackbar v-model="tips.show" :color="tips.color" :timeout="1500" location="top">{{ tips.text }}</v-snackbar>
  30. </div>
  31. </template>
  32. <script setup name="phoneIndex">
  33. import { ref, reactive, defineExpose } from 'vue'
  34. import { setCodeTime } from '@/utils/code'
  35. import { sendSmsCode } from '@/api/common/index'
  36. const phoneRules = ref([
  37. value => {
  38. if (value) return true
  39. return '请输入手机号'
  40. },
  41. value => {
  42. if (value?.length <= 11 && /^1[3456789]\d{9}$/.test(value)) return true
  43. return '请输入正确的手机号码'
  44. }
  45. ])
  46. const tips = reactive({
  47. show: false,
  48. color: '',
  49. text: ''
  50. })
  51. // 手机号区域
  52. const currentArea = ref('0086')
  53. const items = [
  54. { label: '中国大陆-0086', value: '0086' }
  55. ]
  56. const handleChangeCurrentArea = (e) => {
  57. currentArea.value = e.value
  58. }
  59. // 获取验证码
  60. const showCode = ref(true)
  61. const count = ref(0)
  62. const timer = ref(null)
  63. const handleCode = () => {
  64. if (!loginData.phone) {
  65. tips.text = '请输入手机号码'
  66. tips.color = 'warning'
  67. tips.show = true
  68. return
  69. }
  70. count.value = 60
  71. setTime()
  72. getSmsCode()
  73. }
  74. const getSmsCode = async () => {
  75. const query = {
  76. phone: loginData.phone,
  77. scene: 30
  78. }
  79. try {
  80. await sendSmsCode(query)
  81. } catch (error) {
  82. console.log(error, 'error')
  83. }
  84. }
  85. const setTime = () => {
  86. showCode.value = false
  87. timer.value = setInterval(() => {
  88. let number = count.value
  89. if (number > 0 && number <= 60) {
  90. count.value--
  91. setCodeTime(number - 1)
  92. } else {
  93. showCode.value = true
  94. clearInterval(timer.value)
  95. timer.value = null
  96. }
  97. }, 1000)
  98. }
  99. const autoTimer = () => {
  100. count.value = 0
  101. if(!count.value) return
  102. setTime()
  103. }
  104. autoTimer()
  105. const loginData = reactive({
  106. phone: '13229740091',
  107. code: ''
  108. })
  109. const phoneForm = ref()
  110. defineExpose({
  111. loginData,
  112. phoneForm
  113. })
  114. </script>
  115. <style lang="scss" scoped>
  116. .login-code {
  117. width: 62px;
  118. color: var(--default-color);
  119. font-size: 12px;
  120. cursor: pointer;
  121. }
  122. .disable {
  123. width: 72px;
  124. color: grey;
  125. font-size: 12px;
  126. }
  127. .phone-number {
  128. width: 34px;
  129. font-size: 12px;
  130. }
  131. </style>