register.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <script setup lang="ts">
  2. import type { RegisterEmits } from './typings';
  3. import { computed, reactive } from 'vue';
  4. import { useRouter } from 'vue-router';
  5. import { LOGIN_PATH } from '@vben/constants';
  6. import { $t } from '@vben-core/locales';
  7. import {
  8. VbenButton,
  9. VbenCheckbox,
  10. VbenInput,
  11. VbenInputPassword,
  12. } from '@vben-core/shadcn-ui';
  13. import Title from './auth-title.vue';
  14. interface Props {
  15. /**
  16. * @zh_CN 是否处于加载处理状态
  17. */
  18. loading?: boolean;
  19. /**
  20. * @zh_CN 登陆路径
  21. */
  22. loginPath?: string;
  23. }
  24. defineOptions({
  25. name: 'RegisterForm',
  26. });
  27. const props = withDefaults(defineProps<Props>(), {
  28. loading: false,
  29. loginPath: LOGIN_PATH,
  30. });
  31. const emit = defineEmits<{
  32. submit: RegisterEmits['submit'];
  33. }>();
  34. const router = useRouter();
  35. const formState = reactive({
  36. agreePolicy: false,
  37. comfirmPassword: '',
  38. password: '',
  39. submitted: false,
  40. username: '',
  41. });
  42. const usernameStatus = computed(() => {
  43. return formState.submitted && !formState.username ? 'error' : 'default';
  44. });
  45. const passwordStatus = computed(() => {
  46. return formState.submitted && !formState.password ? 'error' : 'default';
  47. });
  48. const comfirmPasswordStatus = computed(() => {
  49. return formState.submitted && formState.password !== formState.comfirmPassword
  50. ? 'error'
  51. : 'default';
  52. });
  53. function handleSubmit() {
  54. formState.submitted = true;
  55. if (
  56. usernameStatus.value !== 'default' ||
  57. passwordStatus.value !== 'default'
  58. ) {
  59. return;
  60. }
  61. emit('submit', {
  62. password: formState.password,
  63. username: formState.username,
  64. });
  65. }
  66. function goToLogin() {
  67. router.push(props.loginPath);
  68. }
  69. </script>
  70. <template>
  71. <div>
  72. <Title>
  73. {{ $t('authentication.createAnAccount') }} 🚀
  74. <template #desc> {{ $t('authentication.signUpSubtitle') }} </template>
  75. </Title>
  76. <VbenInput
  77. v-model="formState.username"
  78. :error-tip="$t('authentication.usernameTip')"
  79. :label="$t('authentication.username')"
  80. :placeholder="$t('authentication.username')"
  81. :status="usernameStatus"
  82. name="username"
  83. type="text"
  84. />
  85. <!-- Use 8 or more characters with a mix of letters, numbers & symbols. -->
  86. <VbenInputPassword
  87. v-model="formState.password"
  88. :error-tip="$t('authentication.passwordTip')"
  89. :label="$t('authentication.password')"
  90. :password-strength="true"
  91. :placeholder="$t('authentication.password')"
  92. :status="passwordStatus"
  93. name="password"
  94. required
  95. type="password"
  96. >
  97. <template #strengthText>
  98. {{ $t('authentication.passwordStrength') }}
  99. </template>
  100. </VbenInputPassword>
  101. <VbenInputPassword
  102. v-model="formState.comfirmPassword"
  103. :error-tip="$t('authentication.confirmPasswordTip')"
  104. :label="$t('authentication.confirmPassword')"
  105. :placeholder="$t('authentication.confirmPassword')"
  106. :status="comfirmPasswordStatus"
  107. name="comfirmPassword"
  108. required
  109. type="password"
  110. />
  111. <div class="relative mt-4 flex pb-6">
  112. <div class="flex-center">
  113. <VbenCheckbox
  114. v-model:checked="formState.agreePolicy"
  115. name="agreePolicy"
  116. >
  117. {{ $t('authentication.agree') }}
  118. <span class="text-primary hover:text-primary-hover">{{
  119. $t('authentication.agreeprivacyPolicy')
  120. }}</span>
  121. &
  122. <span class="text-primary hover:text-primary-hover">
  123. {{ $t('authentication.terms') }}
  124. </span>
  125. </VbenCheckbox>
  126. </div>
  127. <Transition name="slide-up">
  128. <p
  129. v-show="formState.submitted && !formState.agreePolicy"
  130. class="text-destructive absolute bottom-1 left-0 text-xs"
  131. >
  132. {{ $t('authentication.agreeTip') }}
  133. </p>
  134. </Transition>
  135. </div>
  136. <div>
  137. <VbenButton :loading="loading" class="w-full" @click="handleSubmit">
  138. {{ $t('authentication.signUp') }}
  139. </VbenButton>
  140. </div>
  141. <div class="mt-4 text-center text-sm">
  142. {{ $t('authentication.alreadyHaveAccount') }}
  143. <span
  144. class="text-primary hover:text-primary-hover cursor-pointer text-sm font-normal"
  145. @click="goToLogin()"
  146. >
  147. {{ $t('authentication.goToLogin') }}
  148. </span>
  149. </div>
  150. </div>
  151. </template>