基于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.
 
 
 
 

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 rowKey and lazy
  • 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

  1. Do not use window.history.length for navigation - Use Vue Router properly
  2. Do not skip form.value?.clearValidate() - Always clear validation on open
  3. Do not mutate props directly - Use reactive refs
  4. Do not forget onMounted query - Data should load on mount