"Brother, I heard that you have written a lot of pages. I have a page here. How much code do you think you need?"
"Let's see, it's alright, isn't it just a query form. Now everyone uses ProComponent
. It's fast to write with that. I think about 200 lines."
"Well, I know, the official secondary package component library, 200 lines is enough? Well, yes. Wait, does the code you said include operation buttons?"
"Operation buttons? Do you mean the [Add] [Details] buttons on your map?"
"Yes."
"You didn't show me what it looked like after you ordered it!"
"Oh, almost like this."
"Oh~ like this, then this is simple, isn't it just a pop-up form, let's add another 100 lines."
"What about [Deleted]?"
"That's it. 10 lines and you're done."
"Haha, don't worry, there is also a batch deletion!"
"Oh, it's not too difficult. Most of them are Api
that comes with the table. After deleting and refreshing the table request, it's over. It's nothing more than recording the options. I think it's almost the same. But I see that after you check this, there is still a bar at the bottom of the page, and the [Batch Delete] button is put there, which is a bit interesting, but it is not too difficult, and I think it is almost the same after adding about 20 lines."
"Haha, yes, I count, it's almost 340 lines."
"Yeah, if you write such a page, this amount of code is normal."
"What if the options on the previous page are still retained after turning the page?"
"This, how can anyone do this now? These are all ready-made components. You don't mind it, but I don't mind it, and it's not necessary. Whoever loves it will do it."
"Just say you can!"
"You're trying to find fault, aren't you! Besides, it's not difficult, doesn't the antd
form have a preserveSelectedRowKeys
attribute? I think it can be implemented using that, or monitor the selection event of the form, and save a variable. Just click on the page to delete one by one, it won't be too much trouble."
"That said, it's really unnecessary, but I think it's better. If you want to delete more than one, you always have to click several times each time, and after the deletion, the data is not gone, then the second The data of the page will go to the first page, and I will worry about whether I will delete it by mistake.”
"It's alright, as long as you're not too tired, you can write it. I don't think it's a big deal. If you really want to do it, just use that api, and add 20 more lines at most."
"Oh! By the way, I forgot to mention that the number can be floated to see options."
"...You're pretty good at playing, and you have all the data. Just make a set of Popover
and you'll be fine."
"Yeah, that's about 400 lines of code."
"Well, what do you need? It's almost the same."
"Haha, I spent a total of 134 lines of code on this page, do you think it's feasible
"??? How did you do it, show me."
"I looked at it, it's interesting, this component uses a big json, and the configuration is passed in, right? This kind of encapsulation is quite common."
"Yes, you see this is one of the fragments, the query at the top of the table, just specify search: true
."
{
title: '英文名',
key: 'en'
search: true
}
"Like this, I see there is a placeholder on it, why didn't you pass it in."
"Oh, that one is automatically generated, like here, it will generate "Please enter an English name"."
"What if you want to customize it?"
"Of course you can, you need to write it like this."
{
title: '英文名',
key: 'en'
search: {
placeholder: '请输入英文名'
}
}
"Oh~ this can still be an object, right? What if there is a selection box on it?"
"It's also simple, just add options
and type: 'select'
."
{
title: '职业',
key: 'class',
type: 'select',
options: [
{ label: '近卫干员', value: '1' },
{ label: '狙击干员', value: '2' },
{ label: '术师重装', value: '3' },
{ label: '医疗干员', value: '4' },
{ label: '重装干员', value: '5' },
{ label: '辅助干员', value: '6' },
{ label: '特种干员', value: '7' },
{ label: '先锋干员', value: '8' }
],
search: true
}
"Why aren't your options
and type
in the search
object?"
"Haha, you don't know, because if you write it like this, the table can also use this configuration. If it is written in the search
object, you can only use the query area yourself."
"The table can also use this configuration? What's the use of these two for the table."
"The column of the table can be translated by options
. If the data is 1
, then this column will search for this label
according to options
. At this time, the corresponding label
is guard clerk, so the page shows
. .In addition, if the table has a filter, add
filter: true
and the filter will appear."
"Okay, it's quite convenient, what about type
? I can't use the form for this thing."
"Yes, this is actually for dialog
pop-up window editing. In this way, a selection box can also be displayed in the pop-up window."
{
title: '职业',
key: 'class',
type: 'select',
options: [
{ label: '近卫干员', value: '1' },
{ label: '狙击干员', value: '2' },
{ label: '术师重装', value: '3' },
{ label: '医疗干员', value: '4' },
{ label: '重装干员', value: '5' },
{ label: '辅助干员', value: '6' },
{ label: '特种干员', value: '7' },
{ label: '先锋干员', value: '8' }
],
search: true,
+ dialog: true
}
"Oh! I see. After specifying dialog: true
, it will be displayed in the pop-up window, right?"
"Yes, what if it is only displayed in the pop-up window, and the table is not displayed?"
"That can be done like this. Just specify table: false
."
{
title: '职业',
key: 'class',
type: 'select',
options: [
{ label: '近卫干员', value: '1' },
{ label: '狙击干员', value: '2' },
{ label: '术师重装', value: '3' },
{ label: '医疗干员', value: '4' },
{ label: '重装干员', value: '5' },
{ label: '辅助干员', value: '6' },
{ label: '特种干员', value: '7' },
{ label: '先锋干员', value: '8' }
],
dialog: true,
+ table: false
}
"Understood. This is a combination of pop-up windows, forms, and queries, right? By the way, why didn't I see the new code to open the pop-up window?"
"Well, that needs to be added with some code. Just pass addApi
as the request interface, and then specify action="add"
?"
<AySearchTable
title="Amiya 增删改查"
dialogFormExtend={{
fields: fields,
addApi
}}
>
<AyAction action="add">新增</AyAction>
</AySearchTable>
"Is this also possible? Why? Is it difficult to not need to monitor the button click event, then control the display of the pop-up window, request the interface, and then close the pop-up window to refresh the page?"
"Yes, by default, the pop-up window and the form share the same configuration, and most of the new pop-up windows are the same, so after encapsulating all the operations, that's all that's left. Of course, if it's too complicated, or There is no column that can be shared with the table, so define another 'fields: dialogFields'
, and use two fields
completely separate from the table, each with its own."
"Oh, yes, yes, then I understand, the modification is the same."
"Yes, when editing, won't there be a default value? At this time, we can pass the record in and use it as the default value of the form."
const ctrl: AyTableCtrlField = {
render: (value: string, record: Record) => {
return (
<AyCtrl>
<AyAction record={record} action="update">
编辑
</AyAction>
</AyCtrl>
)
}
}
<AySearchTable
title="Amiya 增删改查"
dialogFormExtend={{
fields: fields,
addApi
}}
/>
"Yes, yes! This component turns common operations into instructions."
"Yes, if your details need to request an interface, then you don't need record
. After deleting it, change it to detailApi
and detailParams
, which are the requested interface and the requested parameters respectively. The action="view"
command will automatically return the request. data, as the default value of the form after opening the popup."
<AyAction detailParams={record.sort_id} detailApi={detailApi} action="view">详情</AyAction>
"Got it, that's great! By the way, you just mentioned that the pagination has been deleted. Isn't it easy to use this component?"
"Yes, let me show you, this is a few steps, the first step is to add selectionType="checkbox"
to enable the check; the second step, add selectShowKey="cn"
, use it to determine the selected name when the bubble is suspended, and use the tag tag Wrap it, because the tag tag can be deleted, so after turning the page, you can also click the X on the tag tag to cancel the option, and you don’t need to go to the previous page to cancel the selection; the third step, add the action="delete"
attribute to the delete button , add the action="batch-delete"
attribute to the batch deletion, and add the deleteApi={deleteApi}
interface to the label, and the deletion and batch deletion can be completed."
const ctrl: AyTableCtrlField = {
render: (value: string, record: Record) => {
return (
<AyCtrl>
<AyAction record={record} action="delete">
删除
</AyAction>
</AyCtrl>
)
}
}
<AySearchTable
title="Amiya 增删改查"
selectionType="checkbox"
rowKey="sort_id"
ctrl={ctrl}
selectShowKey="cn"
deleteApi={deleteApi}
>
<AyAction action="batch-delete">批量删除</AyAction>
</AySearchTable>
"Oh, is this ok? That's quite convenient, after all, you don't need to write a bunch of code yourself. By the way, I just looked at the code, and there is renderType: 'html'
on it. What does this do?"
{
title: '描述',
key: 'feature',
width: 200,
renderType: 'html'
}
"you guess?"
"Render this column as html or something?"
"Yeah, other than that, there are unit
datetime
state
and so on, you can look at this."
"Okay, what if what I want isn't there?"
"Just waiting for you to ask this. It seems that you have used other secondary packages. This component provides two methods. The first one can specify the render
method."
{
title: '姓名',
key: 'cn',
search: true,
dialog: {
required: true
},
table: {
// 渲染自定义内容
render: (text: string, record: Record) => {
return (
<div>
<div>{record.cn}</div>
<div>{record.en}</div>
<div>{record.jp}</div>
</div>
)
}
}
},
"Second, it can be registered globally. After registration, it can be used like renderType: 'star'
."
import { registerTableRender, RenderProps } from 'amiya'
/**
* @decs 注册 renderType
* @param renderTypeName string 注册类型名字
* @param text string 当前 col 的数据
* @param record object 当前 row 的数据
* @param field 当前配置配置项
*
* @returns ReactNode
*/
registerTableRender('renderTypeName', ({ text, record, field }: RenderProps) => {
return <span>{text}</span>
})
// 实际使用
const fields = [
{
renderType: 'renderTypeName' // 已经注册过后的名字
}
]
"Good guy, this is no different from me directly render
, but using the registration method and writing the render in other public places will indeed make the current page cleaner."
"Yes, there are two ways to choose freely. Look at it like this, you can save a lot of code, if you use jsx syntax sugar, it will save even more, so only 90 lines of code are needed."
"That's right, the other secondary packages I've seen are missing this, and they all use json. When I use it, there is a large blank space on the right side of the editor, and the code is pulled too long. It's very unpleasant. I like the way you write it. I give them advice, but they don't listen, and it's easy to control things like this."
<AyFields>
<AyField
title="头像"
key="icon"
width={80}
align="center"
renderType="image"
/>
<AyField title="姓名" key="cn" search />
<AyField title="英文名" key="en" search dialog table={false} />
{// ...}
</AyFields>
"It's really saving. I haven't seen such a saving. However, this component is packaged so much, can others use it? Do you understand?"
"Indeed, if you don't introduce the introduction, no one will understand it. So this component supports complete TypeScript prompts, and also prepares a document, which describes in detail how to use the table. You can see the bunch of menus on the left, all in Introducing the Forms API."
"Also, there are full page-level examples for reference as well."
"I saw it. This is a secondary packaged component library. I think there are other components. I will use it and experience it later."
"Okay, waiting for your news."
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。