模板化模块
扁平化组件,将父级组件作为通信组件
-
-
-
-
-
- 1
文件结构
bash
src
├─ components
│ └─ Page.vue // 分页组件
├─ style
│ └─ global.scss // 公共样式
└─ views
└─ Module
├─ components
│ ├─ AddDialog.vue // 新增、编辑表单组件
│ ├─ Form.vue // 搜索表单组件
│ └─ Table.vue // 列表组件
└─ index.vue // 通信组件index.vue(通信组件)
点击查看
vue
<template>
<div class="Container">
<Form ref="RefForm" class="Form" />
<Table ref="RefTable" class="Table" />
<Page ref="RefPage" class="Page" />
<AddDialog ref="RefAddDialog" />
</div>
</template>
<script lang="ts">
export type GetRefs = () => ({
Form: InstanceType<typeof Form>,
Table: InstanceType<typeof Table>,
Page: InstanceType<typeof Page>,
AddDialog: InstanceType<typeof AddDialog>,
})
</script>
<script lang="ts" setup>
import Page from '@/components/Page.vue'
import AddDialog from './components/AddDialog.vue'
import Form from './components/Form.vue'
import Table from './components/Table.vue'
defineOptions({
name: '模板化模块?sort=0'
})
const RefForm = ref(null)
const RefTable = ref(null)
const RefPage = ref(null)
const RefAddDialog = ref(null)
provide('getRefs', () => ({
Form: RefForm.value,
Table: RefTable.value,
Page: RefPage.value,
AddDialog: RefAddDialog.value,
}))
</script>Form.vue(搜索表单组件)
点击查看
vue
<template>
<FormGenerator v-bind="{...formAttrs}" />
</template>
<script lang="ts" setup>
import { FormGenerator } from 'element-plus-generator'
import type { FormAttrs } from 'element-plus-generator/lib/type'
import type { GetRefs } from './../index.vue'
const formAttrs = ref<FormAttrs>({
type: 'search',
model: {},
formOption: [
{
type: 'input',
formItem: {
prop: 'key1',
label: '字段1',
},
},
{
type: 'select',
formItem: {
prop: 'key2',
label: '字段2',
},
control: {
option: [
{
label: '文本1',
value: '值1'
},
]
}
},
{
type: 'date-time-picker',
formItem: {
prop: 'key3',
label: '字段3',
},
},
{
type: 'input',
formItem: {
prop: 'key4',
label: '字段4',
},
},
{
type: 'input',
formItem: {
prop: 'key5',
label: '字段5',
},
},
],
onSubmit: () => {
getRefs().Page.setPageNum(1)
getRefs().Table.getTableData()
}
})
const getRefs = inject<GetRefs>('getRefs')
defineExpose({ model: formAttrs.value.model })
</script>Table.vue(列表组件)
点击查看
vue
<template>
<div class="Table">
<div class="tool">
<el-button type="primary" @click="openAddDialog()">新增</el-button>
</div>
<TableGenerator v-bind="{ ...tableAttrs }">
<template #operation="scope">
<el-button link type="primary" @click="openAddDialog(scope.row.id)">编辑</el-button>
<el-button link type="primary">删除</el-button>
</template>
</TableGenerator>
</div>
</template>
<script lang="ts" setup>
import { TableGenerator } from 'element-plus-generator'
import type { TableAttrs } from 'element-plus-generator/lib/type'
import type { GetRefs } from './../index.vue'
import $api from '@/services'
const $router = useRouter()
const tableAttrs = ref<TableAttrs>({
loading: false,
data: [],
tableOption: [
{
prop: 'key1',
label: '文本1',
}, {
prop: 'key2',
label: '文本2',
}, {
prop: 'key3',
label: '文本3',
}, {
prop: 'key4',
label: '文本4',
}, {
prop: 'key5',
label: '文本5',
},
]
})
async function getTableData() {
const { Form, Page } = getRefs()
tableAttrs.value.loading = true
// const res = await $api.xxx.xxx({
// pageNum: Page.getPageNum(),
// pageSize: Page.getPageSize(),
// ...tableAttrs.value.model,
// })
// tableAttrs.value.data = res?.data.list ?? []
// Page.setTotal(res.total)
tableAttrs.value.loading = false
}
function openAddDialog(id?: number) {
getRefs().AddDialog.openDialog(id)
}
async function del(id: number) {
const bool = await ElMessageBox.confirm('确定删除?')
// bool && await $api.xxx.xxx({id})
ElMessage.success('删除成功')
getRefs().Table.getTableData()
}
onMounted(() => {
getTableData()
})
const getRefs = inject<GetRefs>('getRefs')
defineExpose({ getTableData })
</script>AddDialog.vue(新增、编辑表单组件)
点击查看
vue
<template>
<el-dialog :title="type" v-model="visible" width="500px">
<FormGenerator ref="RefFormGenerator" v-bind="{ ...formAttrs }" />
</el-dialog>
</template>
<script lang="tsx" setup>
import { FormGenerator, GeneratorUtils } from 'element-plus-generator'
import type { FormAttrs, RefFormGenerator } from 'element-plus-generator/lib/type'
import type { GetRefs } from './../index.vue'
import $api from '@/services'
const RefFormGenerator = ref<RefFormGenerator>()
const visible = ref(false)
const type = ref<'新增' | '修改'>('新增')
const option = [
{
label: '文本1',
value: '值1'
},
{
label: '文本2',
value: '值2'
},
]
const formAttrs = ref<FormAttrs>({
type: 'dialog',
model: {},
formOption: [
{
type: 'input',
formItem: {
prop: 'key1',
label: '文本1',
},
},
{
type: 'select',
formItem: {
prop: 'key2',
label: '文本2',
},
control: {
option
}
},
{
type: 'input-number',
formItem: {
prop: 'key3',
label: '文本3',
},
},
{
type: 'radio',
formItem: {
prop: 'key4',
label: '文本4',
},
control: {
radioGroup: option
}
},
{
type: 'checkbox',
formItem: {
prop: 'key5',
label: '文本5',
},
control: {
checkboxGroup: option
}
},
],
onSubmit: () => {
visible.value = false
if (type.value === '新增') {
// await $api.xxx.xxx(form)
} else {
// await $api.xxx.xxx(form)
}
ElMessage.success(`${type.value}成功`)
getRefs().Table.getTableData()
}
})
async function openDialog(id?: number) {
type.value = id ? '修改' : '新增'
visible.value = true
nextTick(async () => {
RefFormGenerator.value()?.resetFields()
if (type.value === '新增') {
} else {
// const res = await $api.xxx.xxx()
// form = res.data
}
})
}
const getRefs = inject<GetRefs>('getRefs')
defineExpose({ openDialog })
</script>Page.vue(分页组件)
点击查看
vue
<template>
<div>
<el-pagination :hide-on-single-page="total <= 50" background @size-change="handleSizeChange"
@current-change="handleCurrentChange" v-model:currentPage="pageNum" layout="prev, pager, next" :page-size="pageSize"
:total="total"></el-pagination>
</div>
</template>
<script lang="ts" setup>
const pageNum = ref(1)
const pageSize = ref(50)
const total = ref(0)
function handleCurrentChange(val: number) {
pageNum.value = val
getRefs().Table.getTableData(null, 'page')
}
function handleSizeChange(val: number) {
pageNum.value = 1
setPageSize(val)
getRefs().Table.getTableData(null, 'page')
}
function getPageSize() {
return pageSize.value
}
function getPageNum() {
return pageNum.value
}
function setPageSize(val: number) {
pageSize.value = val
}
function setPageNum(val: number) {
pageNum.value = val
}
function setTotal(val: number) {
total.value = val
}
const getRefs = inject('getRefs') as Function
defineExpose({ getPageNum, getPageSize, setPageNum, setTotal })
</script>global.scss(公共样式)
点击查看
scss
@mixin flex-init($justify: center, $align: center, $direction: row, $wrap: nowrap) {
display: flex;
flex-direction: $direction;
justify-content: $justify;
align-items: $align;
flex-wrap: $wrap;
}
@mixin grow-shrink($grow: 1, $shrink: -1) {
flex-grow: $grow;
flex-shrink: $shrink;
}
.Container {
width: 100%;
height: 100%;
@include flex-init(flex-start, flex-start, $direction: column);
gap: 12px;
padding: 12px 20px;
box-sizing: border-box;
.Form,
.FormGenerator {
@include grow-shrink(0, 0);
width: 100%;
}
.Table {
width: 100%;
@include grow-shrink(1, 1);
@include flex-init(flex-start, $direction: column);
gap: 10px;
.tool {
width: 100%;
@include flex-init(flex-end);
@include grow-shrink(0, 0);
}
}
.Page {
@include grow-shrink(0, 0);
width: 100%;
@include flex-init(flex-end);
}
}