forked from mengyxu/noob-components
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
163 lines
3.4 KiB
|
3 months ago
|
# 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
|