alwaysApply: false
All list pages must follow this standard structure:
<template>
<ele-page flex-table>
<!-- 1. Search Section -->
<page-search @search="reload" />
<!-- 2. Table Section -->
<common-table ref="pageRef" :pageConfig="pageConfig" :columns="columns" :tools="false">
<!-- Custom Slots -->
<template #status="{ row }">
<dict-data code="user_info_status" type="tag" :model-value="row.status" />
</template>
<!-- Action Column -->
<template #action="{ row }">
<el-button link type="primary" v-permission="'module:action'" @click="handleAction(row)">
[Action Name]
</el-button>
</template>
</common-table>
<!-- 3. Modals/Drawers -->
<page-edit ref="editRef" @success="reload()" />
</ele-page>
</template>
components/page-search.vue)<ele-card :body-style="{ paddingBottom: '8px' }">.<ProSearch> or <ProSearch2>.formItems: Reactive array defining fields (type, label, prop).initKeys: Object defining default values.search event with query parameters.index.vue)pageConfig Object:
pageUrl: Backend API endpoint for pagination (Required).rowKey: Unique identifier (usually 'id').fileName: Default filename for exports.cacheKey: Unique key for column caching.columns Array:
label, prop, align: 'center', width/minWidth.{ columnKey: 'action', label: '操作', width: 200, fixed: 'right', slot: 'action' }.<dict-data> component for status/enum fields.<dict-data code="dict_code" type="tag" :model-value="row.status" /><el-avatar> with <ele-text> in a flex column.@/components/icons (e.g., DownloadOutlined, PlusOutlined).pageRef.value?.reload(where).Confirmations: Use built-in table methods:
pageRef.value?.messageBoxConfirm({
message: 'Confirm text?',
fetch: () => request.post('/api/path', { id: row.id })
});
Batch Operations: Use pageRef.value?.operatBatch({...}).
v-permission directive on all action buttons.'module:submodule:action' (e.g., 'customer:blacklist:remove').import request from '@/utils/request';import CommonTable from '@/components/CommonPage/CommonTable.vue';