1、 First look at the code after implementation
1. View layer
<template> <atable v-loading="isLoading" :data-list="response.list" show-detail :entity="MaterialEntity" @on-detail="onDetail" @on-edit="onEdit" @on-delete="onDelete" @on-sort-change="request.sort = $event; getList()" /> </template> <script lang="ts" setup> import { ref } from 'vue' import { ATable } from '@/airpower/component' import { MaterialEntity } from '@/model/entity/MaterialEntity' import { MaterialService } from '@/service/MaterialService' import { AirRequestPage } from '@/airpower/model/AirRequestPage' import { AirResponsePage } from '@/airpower/model/AirResponsePage' const isLoading = ref(false) const response = ref(new AirResponsePage<MaterialEntity>()) const request = ref(new AirRequestPage(MaterialEntity)) async function getList() { response.value = await MaterialService.create(isLoading).getPage(request.value) } async function onEdit(row: MaterialEntity) { await AirDialog.show(MaterialEditor, row) getList() } async function onDelete(data: MaterialEntity) { Await MaterialService. create (isLoading). delete (data. id, 'Delete material successfully') getList() } async function onAdd() { await AirDialog.show(MaterialEditor) getList() } async function onDetail(data: MaterialEntity) { await AirDialog.show(MaterialDetail, data) getList() } getList() </script>
<atable :entity="MaterialEntity"> <template #materialname="{data}"> I am the material: {{data. materialName}} <template> </template></template></atable>
2. Model layer
import { ClassName, Dictionary, FieldName } from '@/airpower/decorator/Custom' import { TableField } from '@/airpower/decorator/TableField' import { BaseEntity } from '@/base/BaseEntity' /** *# Material Entity * @author Hamm */ @ClassName ('material ') export class MaterialEntity extends BaseEntity { @TableField({ forceShow: true, isCopyField: true, }) @FieldName ('materialName ') materialName!: string @TableField() @FieldName ('specification and model ') materialSpc!: string @Dictionary(MaterialTypeDictionary) @TableField({ showColor: true, width: 100, }) @FieldName ('materialType ') materialType!: MaterialType } /** *# Material Type * @author Hamm */ export enum MaterialType { /** *# Public materials */ PUBLIC = 1, /** *# Private materials */ PRIVATE = 2 } /** *# Item Type Enumeration Dictionary * @author Hamm */ export const MaterialTypeDictionary = AirDictionaryArray.createCustom<imaterialtypedictionary>([ { key: MaterialType.PUBLIC, Label: 'Public material', color: AirColor.SUCCESS, other: 1, }, { key: MaterialType.PRIVATE, Label: 'Private material', color: AirColor.NORMAL, other: 2, }, ])
-
Base class BaseEntity (It contains some fields that must be included by fixed entities, such as id createTime Etc.) -
Method of creating dictionary by dictionary array AirDictionaryArray.createCustom<t extends idictionary>(list: T[]): AirDictionaryArray<t> -
Custom special dictionary IMaterialTypeDictionary (Inherited from standard dictionary IDictionary , some components limit that the standard dictionary and its subclasses or interfaces must be passed in) -
@TableField(config: ITableFieldConfig) Interface for ITableFieldConfig In fact, it contains some general table configurations, as follows: /** *# Table Field Configuration Interface * @author Hamm */ export interface ITableFieldConfig extends IFieldConfig { /** *# Table Field Width */ width?: number; /** *# Enumeration dictionary * --- * ### 💡 If the dictionary is configured with '` ` color ` ` `, you can use the' ` showColor ` ` configuration item to display colors */ dictionary?: AirDictionaryArray<idictionary>; /** *# Conversion rules can be passed in for dates */ dateTimeFormatter?: AirDateTimeFormatter | string; /** *# Whether to display the color status light of enumeration dictionary * --- * ### 💡 If it is displayed, please ensure that the incoming '` dictionary' ` is configured with '` ` color``` */ showColor?: boolean; /** *# Whether the field can be sorted but not by default * --- * ### 💡 ``` Custom ` ` ` For custom sorting, ` ` ` ATable ` ` components will trigger ` ` onSortChange ` ` events */ sortable?: boolean | 'custom'; /** *# Column Alignment */ align?: 'right' | 'left' | 'center'; /** *# Post text * --- * ### 💡 It is generally used to display some text of similar units */ suffixText?: string; /** *# is a field that can be copied * --- * ### 💡 This table column allows one key copy */ isCopyField?: boolean; /** *# Picture Field * --- * ### 💡 Configurable ` ` ` imageWidth ` ` `, ` ` ` imageHeight ` ` and so on */ isImage?: boolean; /** *# The default width of the image is 60 */ imageWidth?: number; /** *# The default height of the image is 60 */ imageHeight?: number; /** *# Empty data string * --- * ### 💡 Global disclosure can be made in ` ` ` AirConfig. defaultTableEmptyValue ` ` `, *This configuration item will be used preferentially. Only normal fields and mount fields are supported */ emptyValue?: string //There are also too many configurations. Don't be afraid of trouble. Anyway, there is an automatic prompt of '' TypeScript '', which is great. }
3. Service layer
/** *# Material Interface Service * @author Hamm */ export class MaterialService extends AbstractBaseService<materialentity> { entityClass = MaterialEntity baseUrl = 'material' }
2、 Why do you write that
1. Based on TypeScript
Code hints and data type constraints for
2. Based on Java Annotation
Implementation of decorator configuration of ideas
3. Front end development based on face object thinking
-
No new idea: carrying tutorial, teaching you how to prepare environment and get started, teaching you how to use interface To constrain the data structure -
Misleading users: As mentioned above, everyone forgot class extends implements The existence of -
Type Gymnastics: As I commented under many Nuggets articles before Type gymnastics is the most fun of Typescript, and it is also the last thing that should not exist -
There are too many: next time I will attack, the article will be biased.
TypeScript Prevalence in the front end Decorator Popularization in the front end php Decorators are starting to come out) -
Object oriented, generic, AOP idea, dependency injection and other back-end concepts are transferred to the front Vue.js The emergence of such a relatively low entry front-end framework -
The emergence of articles such as death anxiety at the front end of selling -
There are still a lot of it
3、 That's all
4、 See this column for more articles