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.
6.5 KiB
6.5 KiB
Views Components
View-level CRUD management components.
Overview
Views are page-level components that provide full CRUD operations for domain entities. Each view follows a consistent pattern using shared components from noob-mengyxu.
Components
| Component | File | Purpose |
|---|---|---|
| User | views/user.vue |
User management with password reset |
| Role | views/role.vue |
Role management with permission assignment |
| Dictionary | views/dictionary.vue |
Hierarchical dictionary with lazy loading |
| Config | views/config.vue |
Configuration management |
| Buffer | views/buffer.vue |
Buffer/warning management |
| Permission | views/permission.vue |
Permission tree management |
| Status | views/status.vue |
Status management |
| Log | views/log.vue |
Log viewing |
| Scope | views/scope.vue |
Scope management |
Standard View Pattern
All view components follow the same structure:
<template>
<SearchRow @query="query" @add="addItem">
<!-- Optional filter inputs -->
</SearchRow>
<ListTable :props="props" :data="result">
<template #action="{ row }">
<TableAction @modify="modify" @del="delate">
<!-- Optional extra actions -->
</TableAction>
</template>
</ListTable>
<el-dialog v-model="flag.modify">
<ModifyForm :param="item" :rules="rules" :items="items" @confirm="confirm" />
</el-dialog>
</template>
Key Imports
import { Api, ListTable, SearchRow, NoobInput, NoobSelect,
TableAction, ModifyForm, Element, PageExample, PageResult } from "noob-mengyxu";
Props Configuration
Column definitions using i18n keys:
const props = [
{ i18n: 'user.prop.0', code: 'userId', width: 120 }, // i18n key, data field, width
{ i18n: 'user.prop.3', code: 'name', width: 120 },
{ i18n: 'user.prop.4', code: 'phone', width: 180 },
{ i18n: 'user.prop.7', code: 'action', slot: true, width: 180, fixed: 'right' }
]
Column Options
| Option | Type | Description |
|---|---|---|
i18n |
string | i18n key for column header |
code |
string | Field name in data object |
width |
number | Column width in pixels |
slot |
boolean | Enable slot for custom rendering |
fixed |
string | Fix column position ('right', 'left') |
dict |
string | Dictionary key for value translation |
type |
string | Column type (e.g., 'action') |
Form Items Configuration
const items = [
{ i18n: 'user.prop.0', code: 'userId', slot: true }, // slot = custom input
{ i18n: 'user.prop.1', code: 'password', type: 'password', noModify: true },
{ i18n: 'user.prop.2', code: 'roles', slot: true },
{ i18n: 'user.prop.3', code: 'name' }
]
Item Options
| Option | Type | Description |
|---|---|---|
i18n |
string | i18n key for label |
code |
string | Field name |
slot |
boolean | Custom input via slot |
type |
string | Input type (password, etc.) |
noModify |
boolean | Skip in modify mode |
dict |
string | Dictionary for select options |
Rules Configuration
Validation rules using Element validators:
const { SimpleRequired, Password, Username, Name, IdCard, Phone, Email } = Element;
const rules = {
userId: [new Username()],
password: [new Password()],
roles: [{type: 'array', required:true, message: t('rule.pleaseSelect') + t('user.prop.2'), trigger: 'blur'}],
name: [new SimpleRequired('user.prop.3'), new Name()],
idCard: [new IdCard()],
phone: [new Phone()],
email: [new Email()]
}
CRUD Operations Pattern
const { list, add, set, del } = Api.user;
const result = ref(new PageResult());
const example = reactive<any>(new PageExample());
const query = () => {
list(example).then((rsp: any) => result.value = rsp)
}
const addItem = () => {
item.value = {};
form.value?.clearValidate();
flag.add = true;
flag.modify = true;
}
const modify = (row) => {
item.value = JSON.parse(JSON.stringify(row));
form.value?.clearValidate();
flag.add = false;
flag.modify = true;
}
const delate = (row) => {
Element.confirm(t('delete.0'), t('delete.1')).then(() => {
del(row).then(query);
})
}
const confirm = () => {
const api = flag.add ? add : set;
api(item.value).then(rsp => {
if (rsp) {
query();
flag.modify = false;
}
})
}
onMounted(() => {
query();
});
Code Examples
User View (views/user.vue)
User management with role assignment and password reset.
Key features:
- User CRUD with md5 password hashing
- Role multi-select
- Reset password action
- Action buttons with status check (
row.status != 'R')
const { list, add, set, del, reset } = Api.user;
const { roles } = useStore().state;
// Reset password flow
const resetPass = row => {
Element.confirm(t('user.reset.1'), t('user.reset.2')).then(() => {
reset(row);
})
}
Role View (views/role.vue)
Role management with permission tree assignment.
Key features:
- Permission tree with
el-tree - Cascading check with
check-strictly - Vuex state update on role changes
const { tree } = Api.permission;
const permission = (row) => {
role.value = JSON.parse(JSON.stringify(row));
permissionTree.value?.setCheckedNodes(role.value.permissions);
flag.per = true;
}
const setPermission = () => {
role.value.permissions = permissionTree.value?.getCheckedKeys();
set(role.value).then(rsp => {
if (rsp) {
query();
flag.per = false;
}
})
}
Dictionary View (views/dictionary.vue)
Hierarchical dictionary with lazy loading.
Key features:
- Lazy loading with
rowKeyandlazy - Tree structure transformation in query callback
- Parent-child relationship support
const query = () => {
list(example).then((rsp: any) => {
result.value = rsp;
result.value.data.forEach((i: any) => {
i.child = i.children;
i.children = [];
i.hasChildren = true;
})
})
}
Anti-Patterns
- Do not use
window.history.lengthfor navigation - Use Vue Router properly - Do not skip
form.value?.clearValidate()- Always clear validation on open - Do not mutate props directly - Use reactive refs
- Do not forget
onMountedquery - Data should load on mount