
最近需要编写一个后台管理系统,涉及到大量表格表单,本身这些内容如果直接用 Django 来做,可能就没我们前端什么事情了,但是后端是新来的 JAVA 团队,前后端分离开发模式,所以前端工作量非常大,于是抽象了一个接口类似于 django 的前端框架。
基于 react class component 编写和使用了 ant design UI 库,通过配置的形式直接实现一个管理页面的增删改查以及分页功能,能够减少大量的逻辑代码,不由得感慨面向对象编程的伟大,以及 django 这个框架设计的精妙。
一个页面的实现大致如下所示:
import { RegisterRoute } from '@src/components/router' import { ModelForm } from '@src/core/model/form' import { RemoteDataChoiceWidget } from '@src/core/model/widget' import { Display, ModelAdmin } from '@src/core/template/model-admin' import { TemplateTablePagination } from '@src/core/template/template-table' import { UploadWidget } from '@src/core/widgets/upload-widget' import { $fetch } from '@src/utils/network' import { Switch } from 'antd' class SouceChoiceWidget extends RemoteDataChoiceWidget<any, any> { type = 1 async getRemoteData(): Promise<{ label: string; value: string | number }[]> { const result = await $fetch.post<any, Business.SourceInfo[]>('investment/lead/way/list', { type: this.type }) return result.map(val => { return { label: val.name, value: val.id } }) } } class ClueSourceChoiceWidget extends SouceChoiceWidget { type = 0 } class Form extends ModelForm { name = ModelForm.InputField({ verboseName: '线索名称', }) cOntactPerson= ModelForm.InputField({ verboseName: '联系人', }) cOntactTel= ModelForm.PhoneNumberField({ verboseName: '联系电话', }) fromType = ModelForm.InputField({ verboseName: '线索来源', widget: ClueSourceChoiceWidget }) wayType = ModelForm.InputField({ verboseName: '渠道类型', widget: SouceChoiceWidget }) file = ModelForm.InputField({ verboseNae: '附件', widget: UploadWidget }) } interface AppInfo { id: number; parkId: number; appName: string; appCate: number; appUrl: string; isDisabled: number; createAt: string; createBy: string; } @RegisterRoute('clue/list') export default class App extends ModelAdmin<any, any> { filters: string[] = ['name'] listDisplay: string[] = [ 'name', 'type', 'disabled', 'action', ] getModel(): new () => ModelForm { return Form } async getTableDataSource(pagination: TemplateTablePagination, filters?: any) { const data = Object.assign({}, filters || {}, { pageSize: pagination.pageSize, pageNo: pagination.current, }) const result = await $fetch.post<any, App.Pagination<AppInfo>>( '/smart-park-invest/investmentLead/page', data ) return result } async onFormAddSubmit( composeValues: any, formValues: any ) { await $fetch.post('/smart-park-invest/investment/lead/way/add', { ...formValues }) } async onFormUpdateSubmit( composeValues: any, formValues: any, initialValues: any ) { await $fetch.post('/smart-park-invest/investment/lead/way/update', { ...formValues, id: initialValues.id, }) } getaddFormInitialValues() { return null } async getUpdateFormInitialValues(record: any) { return record } async onConfirmDeleteRow(record: any) { await $fetch.post(`/smart-park-invest/investment/lead/way/delete/${record.id}`) } @Display({ name: 'disabled', title: '启用', }) displayDisabled(_: any, record: any) { return ( <Switch size="small" checked={record.enable} OnChange={(val) => this.setAppEnabel(record, val)} /> ) } @Display({ name: 'action', title: '操作', }) displayAction(_: any, record: any) { return ( <div> <span className="ml-2 text-blue-400 cursor-pointer" OnClick={() => this.modifyRowData(record)}> 编辑 </span> <span className="ml-2 text-red-400 cursor-pointer" OnClick={() => this.deleteRowData(record)}> 删除 </span> </div> ) } async setAppEnabel(record: any, bool: boolean) { await $fetch.post('/smart-park-invest/investment/lead/way/update', { id: record.id, enable: bool }) this.notifyDataChange() } } 虽然 react 现在都在推崇 hooks 编程,甚至官方文档都不再教学 class 组件,但 class component 在有些场景还是很好用的。
1 shakaraka PRO 首推 angular |
2 wanguorui123 Apr 20, 2023 Class 组件大多数时候比较好,面向对象编程就是分离关注点,专注于做好每件小事,把大事化解掉,而不是面向过程写出无数个冗长且不可复用的代码。 |