乐趣区

关于前端:100-左右实现查询表格真的假的一起来体验一下-Amiya-的魅力

“老哥,据说你写的页面挺多的,我这儿有一个页面,你感觉你须要多少代码?”

“我看看,也还行吧,不就是个查问表格嘛,当初大家都用 ProComponent 了,用那个写一下很快的。我想想,差不多 200 行左右就能够了吧。”

“那个呀,我晓得,官网的二次封装组件库,200 行就能够了吗?嗯,能够。等等,你说的代码是否蕴含了操作按钮?”

“操作按钮?是指你图上的【新增】【详情】这些按钮吗?”

“是啊。”

“点了之后长啥样呀,你也没给我看呀!”

“哦,差不多长这个样。”

“哦~ 这样子啊,那这个简略,不就是个弹窗表单嘛,撑死再加个 100 行吧。”

“那【删除】呢?”

“就这。10 行就搞定了吧。”

“哈哈,你别着急嘛,还有批量删除呢!”

“哦哦,这也没多难啊,大部分都是表格自带的 Api,删除完刷新下表格申请就完事儿了。无非就是记录下选项嘛,再给个 10 行我感觉就差不多了。不过我看你这勾选之后,页面上面还有个条,把【批量删除】按钮放那里了,有点意思,不过也没多难,再加个 20 行左右我感觉差不多了。”

“哈哈,是的,我算算,这差不多曾经 340 行了吧。”

“是啊,写这样一个页面的话,这点代码量很失常。”

“那如果翻页后,依然保留上个页面的选项呢?”

“这个呀,当初哪有人做这个呀,这都是现成的组件,你不嫌麻烦我还嫌麻烦呢,而且又不是必须的,爱谁谁做。”

“你就说你会不会吧!”

“你是成心找茬是吧!再说了,这也不难,antd 表格不是有个 preserveSelectedRowKeys 属性吗,我感觉能够用那个实现,或者监听下表格的抉择事件,存个变量就好了。切实不行,就点页面单个删除呗,也没多麻烦吧。”

“说是这么说,的确也没必要,但我感觉有更好,如果要删除多个的话,每次删除总是要多点几次,而且删除完之后,数据不是没了嘛,那第二页的数据就会跑到第一个页面来,就会放心本人会不会删错。”

“还行吧,只有你不嫌累,你就写吧。我感觉也没啥,如果真要做,用那个 api 就好了,顶多再加个 20 行吧。”

“哦!对了,我遗记说了,这个数字悬浮下来是能看到选项的。”

“… 你玩的还挺花,数据都有,搞个 Popover 套一下,就能够了吧。”

“是的,这么样一算的话,差不多有 400 行代码了吧。”

“嗯,你需要多嘛,差不多差不多。”

“哈哈,这个页面我总共花了 134 行代码,你感觉可行

“???你怎么做到的,给我看看。“

查看表格示例代码

“我看了一下,有意思,这个组件用了一个大 json,把配置传进去了是吧,这种封装还挺常见的。”

“是的,你看这是其中一个片段,表格的顶部查问,只须要指定 search: true 就能够了。”

{
  title: '英文名',
  key: 'en'
  search: true
}

“这样子啊,那下面我看有 placeholder 呀,怎么没看你传进去。”

“哦,那个是主动生成的,像这里,会生成"请输出英文名"。”

“那如果要自定义呢?”

“当然也能够,须要这样子写。”

{
  title: '英文名',
  key: 'en'
  search: {placeholder: '请输出英文名'}
}

“哦~ 这还能是个对象是吧,那如果下面是个抉择框呢?”

“也简略,增加 optionstype: '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
}

“你这 optionstype 为什么没有放在 search 对象外面的呀?”

“哈哈,这你就不晓得了吧,因为这样子写的话,表格也能够用这个配置,写在 search 对象外面的话,就只能查问区域本人用了。”

“表格也能够用这个配置?表格要这俩有啥用。”

“表格这一列,能够通过 options 翻译,如果数据是个 1,那么这一列就会依据 options 去寻找这个 label,这时候对应的 label近卫干员 ,所以页面上显示的就是 近卫干员。另外如果表格有筛选,增加 filter: true 就会呈现筛选了。”

“能够,还挺不便的,那 type 呢?这货色表格用不到吧。”

“是的,这个的话,其实是给 dialog 弹窗编辑用的。这样子的话能够让弹窗外面也展现一个抉择框了。”

{
  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
}

“哦哦!明确了,指定了 dialog: true 后,就会在弹窗外面显示了是吧。”

“是的,那如果只在弹窗里展现,而表格不展现呢?”

“那能够这样子做。指定 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
}

“明确了。这是把弹窗、表格、查问揉在一起了是吧,对了,我怎么没有看到新增关上弹窗的代码呢?”

“那个呀,那个须要再加点代码。把 addApi 作为申请接口传进去,再指定 action="add" 就好了?”

<AySearchTable
  title="Amiya 增删改查"
  dialogFormExtend={{
    fields: fields,
    addApi
  }}
>
  <AyAction action="add"> 新增 </AyAction>
</AySearchTable>

“这也能够?为什么?难到不须要监听按钮点击事件,而后管制弹窗显示,再申请接口,之后敞开弹窗刷新页面吗?”

“是的,这里默认认为弹窗和表格共用一个配置,且弹窗新增大多都是千篇一律的,所以把所有的操作封装了一下,就只剩下这么点了。当然如果太过简单,或者跟表格都没有什么能够共用的列,就再定义一个 'fields: dialogFields',和表格齐全离开用俩 fields,各用各的。”

“哦哦,能够能够,那我了解了,批改也是同理吧。”

“是的,编辑的时候,不是会有默认值吗?此时咱们把 record 传进去,当作表单的默认值就能够了。”

const ctrl: AyTableCtrlField = {render: (value: string, record: Record) => {
    return (
      <AyCtrl>
        <AyAction record={record} action="update">
          编辑
        </AyAction>
      </AyCtrl>
    )
  }
}

<AySearchTable
  title="Amiya 增删改查"
  dialogFormExtend={{
    fields: fields,
    addApi
  }}
/>

“能够,能够!这个组件把罕用的操作都变成指令了啊。”

“是的呀,如果你的详情是须要申请接口的,那就不须要 record 了,删掉之后改成 detailApidetailParams,别离是申请的接口和申请的参数,action="view" 指令会主动的把申请返回的数据,作为关上弹窗后表单的默认值的。”

<AyAction detailParams={record.sort_id} detailApi={detailApi} action="view"> 详情 </AyAction>

“明确了,十分的棒!对了你刚刚还说到分页删除了,用这个组件是不是也很简略啊?”

“是的,我给你看一下,这个多个几步,第一步,先增加 selectionType="checkbox" 开启勾选;第二步,增加 selectShowKey="cn",让气泡悬浮时用它来决定展现选中的名称,并用 tag 标签裹住,因为 tag 标签能够删除的,这样子翻页之后也能够点击 tag 标签下面的 X,来勾销选项,不必再翻到上一页勾销抉择了;第三步,在删除按钮上增加 action="delete" 属性,批量删除上增加 action="batch-delete" 属性,标签上增加 deleteApi={deleteApi} 接口,就能够实现删除和批量删除的动作了。”

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>

“哦哦,这样子就能够了吗?那还挺不便的,毕竟不须要本人写一堆代码来写。对了,我方才看了下代码,下面有个 renderType: 'html',这是什么作用。”

{
  title: '形容',
  key: 'feature',
  width: 200,
  renderType: 'html'
}

“你猜猜?”

“把这一列渲染成 html 之类的?”

“是呀,除此之外,还有 unit datetime state 等等类型,你能够看看这个。”

查看自定义类型

“能够,那如果我要的这外面没有呢?”

“就等着你问这个呢,看来你用过其它的二次封装呀,这个组件提供两种形式,第一种能够指定 render 办法。”

{
  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>
      )
    }
  }
},

“第二种,能够全局注册,注册完之后,能够像 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' // 曾经注册过后的名字}
]

注册自定义表单类型

“好家伙,这跟我间接 render 也没什么区别嘛,不过用注册的办法,把 render 写在其它公共的中央的话,的确会让以后页面洁净一点。”

“是的,两种形式自由选择。你看这样子一套下来,你看,是不是省了很多代码,如果你用 jsx 语法糖的话会更省,那样子只须要 90 行代码了。”

“对哦,我见到的其它二次封装就是少了这个,都用 json,用起来编辑器左边空白一大片,代码又拉的老长,挺不爽的,你这样子写法我挺喜爱的,我跟他们提倡议,他们都不听的,还云云这样容易管制什么的。”

 <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>

“真能省,还没见过这么能省的,不过,这个组件封装的这么多,他人会用吗?用的明确吗?”

“的确,如果不介绍介绍的话,没人用的明确。所以这个组件反对残缺的 TypeScript 提醒,也筹备了文档,具体地介绍了表格的应用形式,你看左侧那一堆菜单,都是在介绍表格 api 的。”

“而且,也有残缺的页面级别的示例,也能够做参考。”

表格其它示例

“我看到了,这是个二次封装的组件库吧,我看还有其它组件,等我回头用用看体验一下。”

“好的,等你音讯。”

Amiya 二次封装文档地址

退出移动版