基于vue3.0和element-plus的组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
3.4 KiB

# Common Components
> Shared management components (login, etc.).
---
## Overview
Common components are shared UI elements used across the management module, primarily login components and other reusable pieces.
---
## Components
| Component | File | Purpose |
|-----------|------|---------|
| Login | `common/login.vue` | User login form |
| Login2 | `common/login2.vue` | Alternative login layout |
---
## Login Component (`login.vue`)
User authentication form with md5 password hashing.
### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `logo` | String | null | Logo image URL |
### Events
| Event | Payload | Description |
|-------|---------|-------------|
| `login` | - | Emitted after successful login |
### Key Features
- Form validation with Element Plus `FormInstance`
- Enter key support for quick submit
- MD5 password hashing before API call
- Vuex state manipulation for layout (hides header/aside on login)
- Dynamic routing (back or home based on history)
### Implementation Pattern
```vue
<template>
<el-form :model="param" ref="loginForm" :rules="rules">
<NoobInput v-model="param.userId" :placeholder="t('pwd.userId')" />
<NoobInput v-model="param.password" type="password" :placeholder="t('pwd.pwd')" />
<NoobButton @click="login">{{ t('pwd.login') }}</NoobButton>
</el-form>
</template>
<script setup>
const emit = defineEmits(["login"]);
const loginForm = ref<FormInstance>();
const login = () => {
if (!loginForm.value) return;
loginForm.value?.validate((valid, fields) => {
if (valid) {
loginConfirm(param.value);
}
});
};
</script>
```
### Vuex Layout Control
On mount, login page resets layout:
```typescript
onBeforeMount(() => {
state.size.headHeight = '0px';
state.size.asideWidth = '0px';
commit("initSize");
});
```
### Login API Call
```typescript
import md5 from "js-md5";
const loginConfirm = user => {
const param = JSON.parse(JSON.stringify(user));
param.password = md5(param.password);
Api.pub.login(param).then(rsp => {
if (rsp) {
if (window.history.length <= 1) {
router.push('/');
} else {
router.back();
}
dispatch('login');
}
})
};
```
### Enter Key Support
```typescript
const enter_up = (e) => {
if (e.keyCode == 13 || e.keyCode == 100) {
login();
}
};
onMounted(() => {
document.addEventListener('keyup', enter_up);
});
onBeforeUnmount(() => {
document.removeEventListener('keyup', enter_up);
});
```
---
## Validation Rules
Uses Element validators from `noob-mengyxu`:
```typescript
const { SimpleRequired } = Element;
const rules = {
userId: [new SimpleRequired('pwd.userId')],
password: [new SimpleRequired('pwd.pwd')]
}
```
---
## Login2 Component (`login2.vue`)
Alternative login layout - check source for specific variations.
---
## Common Exports (`common/index.ts`)
```typescript
import Login from './login.vue';
import Login2 from './login2.vue';
export default { Login, Login2 };
```
---
## Anti-Patterns
1. **Do not skip `clearValidate()`** - Always clear form validation on submit
2. **Do not use `window.history.length`** - This is a known anti-pattern in the codebase
3. **Do not forget `onBeforeUnmount`** - Clean up event listeners to prevent memory leaks
4. **Do not send plain passwords** - Always hash with md5 first