Forráskód Böngészése

refactor: 抽取登录field

xyh 2 éve
szülő
commit
8fe457b303

+ 1 - 0
src/components/index.ts

@@ -0,0 +1 @@
+export * from './login-field';

+ 41 - 0
src/components/login-field/Field.vue

@@ -0,0 +1,41 @@
+<script setup lang='ts'>
+import {ElInput} from 'element-plus';
+import {useField} from 'vee-validate';
+import {toRefs} from 'vue';
+
+defineOptions({name: 'LoginField'});
+
+type Props = {
+  name: string;
+  placeholder: string;
+  type?: string;
+};
+
+const props = defineProps<Props>();
+const {name, placeholder, type} = toRefs(props);
+
+const {value, errorMessage, name: inputName} = useField<string>(name.value);
+</script>
+
+<template>
+  <ElInput
+    v-model="value"
+    :name="inputName"
+    :placeholder="placeholder"
+    :type="type"
+  >
+    <template #prefix>
+      <slot name="prefix" />
+    </template>
+    <template #suffix>
+      <slot name="suffix" />
+    </template>
+  </ElInput>
+  <p :class="['error-tip', {'error-top-hidden': !errorMessage}]">
+    {{errorMessage}}
+  </p>
+</template>
+
+<style scoped lang='css'>
+@import './index.css';
+</style>

+ 12 - 0
src/components/login-field/index.css

@@ -0,0 +1,12 @@
+.error-tip {
+  height: 14px;
+  padding: 0 34px;
+  margin-top: 4px;
+  font-size: 14px;
+  line-height: 14px;
+  color: red;
+}
+
+.error-top-hidden {
+  visibility: hidden;
+}

+ 1 - 0
src/components/login-field/index.ts

@@ -0,0 +1 @@
+export {default as LoginField} from './Field.vue';

+ 0 - 11
src/pages/login/login-info/hooks.ts

@@ -1,11 +0,0 @@
-import {useField} from 'vee-validate';
-import {FormState} from '../hooks';
-
-export function useFieldItem(key: keyof FormState) {
-  const {value, errorMessage} = useField<string>(key, void 0, {
-    validateOnValueUpdate: true,
-    validateOnMount: false,
-  });
-
-  return {value, errorMessage};
-}

+ 10 - 28
src/pages/login/login-info/index.vue

@@ -1,14 +1,14 @@
 <script setup lang="ts">
 import {ref} from 'vue';
-import {ElInput, ElIcon, ElButton} from 'element-plus';
+import {ElIcon, ElButton} from 'element-plus';
 import userIcon from '@assets/images/login/user.webp';
 import posswordIcon from '@assets/images/login/passowrd.webp';
 import enterpriseIcon from '@assets/images/login/enterprise.webp';
 import {PreviewOpen, PreviewCloseOne} from '@icon-park/vue-next';
 import {useToggle} from '@vueuse/core';
 import {RouterLink} from 'vue-router';
-import {useFieldItem} from './hooks';
 import {useI18n} from 'vue-i18n';
+import {LoginField} from '@components';
 
 defineOptions({name: 'LoginInfo'});
 
@@ -20,12 +20,6 @@ function onTabClick(value: number) {
 const [isPassword, togglePassword] = useToggle(true);
 const [remberPassword, toggleRemberPassword] = useToggle();
 
-const {value: nameValue, errorMessage: nameErrorMessage} = useFieldItem('name');
-const {value: passwordValue, errorMessage: passwordErrorMessage}
-  = useFieldItem('password');
-const {value: companyValue, errorMessage: companyErrorMessage}
-  = useFieldItem('company');
-
 const {t} = useI18n();
 </script>
 
@@ -48,21 +42,16 @@ const {t} = useI18n();
   </div>
 
   <div class="info">
-    <ElInput
-      v-model="nameValue"
-      name="userName"
+    <LoginField
+      name="name"
       :placeholder="t('login.placeholder.userName')"
     >
       <template #prefix>
         <img :src="userIcon" class="input-icon" />
       </template>
-    </ElInput>
-    <p :class="['error-tip', {'error-top-hidden': !nameErrorMessage}]">
-      {{nameErrorMessage}}
-    </p>
+    </LoginField>
 
-    <ElInput
-      v-model="passwordValue"
+    <LoginField
       name="password"
       :placeholder="t('login.placeholder.password')"
       :type="isPassword ? 'password' : 'text'"
@@ -80,23 +69,16 @@ const {t} = useI18n();
           <PreviewCloseOne v-if="isPassword" theme="filled" fill="#B6B6B6" />
         </ElIcon>
       </template>
-    </ElInput>
-    <p :class="['error-tip', {'error-top-hidden': !passwordErrorMessage}]">
-      {{passwordErrorMessage}}
-    </p>
+    </LoginField>
 
-    <ElInput
-      v-model="companyValue"
-      name="userName"
+    <LoginField
+      name="company"
       :placeholder="t('login.placeholder.company')"
     >
       <template #prefix>
         <img :src="enterpriseIcon" class="input-icon" />
       </template>
-    </ElInput>
-    <p :class="['error-tip', {'error-top-hidden': !companyErrorMessage}]">
-      {{companyErrorMessage}}
-    </p>
+    </LoginField>
 
     <div class="operation">
       <span