V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
viewweiwu
V2EX  ›  分享创造

100 左右实现查询表格?真的假的?一起来体验一下 Amiya 的魅力。

  •  1
     
  •   viewweiwu ·
    viewweiwu · 2022-03-01 11:16:45 +08:00 · 3555 次点击
    这是一个创建于 1002 天前的主题,其中的信息可能已经有所发展或是发生改变。

    image.png

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

    “我看看,也还行吧,不就是个查询表格嘛,现在大家都用 ProComponent 了,用那个写一下很快的。我想想,差不多 200 行左右就可以了吧。”

    “那个呀,我知道,官方的二次封装组件库,200 行就可以了吗?嗯,可以。等等,你说的代码是否包含了操作按钮?”

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

    “是啊。”

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

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

    image.png

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

    “那 [删除] 呢?”

    image.png

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

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

    image.png

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

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

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

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

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

    “你就说你会不会吧!”

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

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

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

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

    image.png

    “...你玩的还挺花,数据都有,搞个 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 就会出现筛选了。”

    image.png

    “可以,还挺方便的,那 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 的。”

    image.png

    “而且,也有完整的页面级别的示例,也可以做参考。”

    表格其它示例

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

    “好的,等你消息。”

    Amiya 二次封装文档地址

    37 条回复    2022-03-09 13:42:37 +08:00
    efaun
        1
    efaun  
       2022-03-01 11:20:02 +08:00
    好家伙, 推广都得写小作文了?
    viewweiwu
        2
    viewweiwu  
    OP
       2022-03-01 11:50:21 +08:00
    @efaun 才疏学浅,随便写写
    est
        3
    est  
       2022-03-01 12:05:23 +08:00
    VB 里做双向绑定带搜索分页插入编辑的表格,一行代码都不需要写。水晶报表一个控件搞定。
    hades97
        4
    hades97  
       2022-03-01 13:05:16 +08:00
    这种二次封装的 crud 组件,你们的文档算是写的清晰的
    rekulas
        5
    rekulas  
       2022-03-01 13:07:55 +08:00
    推广对话有点意思,期待下一波推广走漫画流
    cheng6563
        6
    cheng6563  
       2022-03-01 13:57:12 +08:00
    我以为是 100 块
    viewweiwu
        7
    viewweiwu  
    OP
       2022-03-01 14:13:56 +08:00
    @cheng6563 😂
    3dwelcome
        8
    3dwelcome  
       2022-03-01 14:24:02 +08:00
    我觉得楼主方向不对,市面上对二次封装需求量很少。

    应该把表格控件的开发目标,定位在 notion 通用组件上。

    能玩出花。
    summer2019
        9
    summer2019  
       2022-03-01 14:25:50 +08:00 via iPhone
    玩的挺花,mark 一下
    sanggao
        10
    sanggao  
       2022-03-01 14:31:50 +08:00
    有 amis 好用不?
    viewweiwu
        11
    viewweiwu  
    OP
       2022-03-01 14:44:39 +08:00
    @3dwelcome 感谢你的建议,我会尝试开发更多的通用组件的。另外市面上二次封装也不少,antd 自己就有一片天地,pro components 、sula ,也有很多的呢。
    viewweiwu
        12
    viewweiwu  
    OP
       2022-03-01 14:52:10 +08:00
    @sanggao 我不知道,感觉方向不一样,amiya 只做了 antd 的封装,在保证可维护性的前提下,进行封装。如果有机会你可对比使用下,期待你的反馈。
    viewweiwu
        13
    viewweiwu  
    OP
       2022-03-01 14:54:30 +08:00
    @est 封装市场应该是多样化的,百家齐放,各取所需,如果你觉得一行代码都不用写更适合你现在场景话,那你就应该继续用下去。
    viewweiwu
        14
    viewweiwu  
    OP
       2022-03-01 14:55:32 +08:00
    @hades97 感谢认可! CRUD 只是其中一部分,这次只介绍了表格,下次会介绍下其它的组件。
    viewweiwu
        15
    viewweiwu  
    OP
       2022-03-01 15:00:28 +08:00
    @rekulas 是吗,漫画会更有意思吗?也许我可以试试
    viewweiwu
        16
    viewweiwu  
    OP
       2022-03-01 15:00:47 +08:00
    @xzb0797 感谢支持
    aitaii
        17
    aitaii  
       2022-03-01 16:20:30 +08:00
    什么游戏
    C603H6r18Q1mSP9N
        18
    C603H6r18Q1mSP9N  
       2022-03-01 18:15:35 +08:00
    很赞
    lizhesystem
        19
    lizhesystem  
       2022-03-01 19:09:51 +08:00
    我记得有个基于 element 的,AVUE 也是封装了 CRUD ,这东西挺适合搬砖的
    EscYezi
        20
    EscYezi  
       2022-03-01 19:31:04 +08:00 via iPhone
    看见 Amiya 就点进来了,果然🤣
    viewweiwu
        21
    viewweiwu  
    OP
       2022-03-01 20:40:33 +08:00
    @EscYezi 果然啥?
    EscYezi
        22
    EscYezi  
       2022-03-01 20:46:22 +08:00 via iPhone   ❤️ 1
    @viewweiwu #21 博士,代码还没写完,现在还不能休息哦
    2218675712
        23
    2218675712  
       2022-03-01 20:47:51 +08:00
    类似于百度 amis
    2218675712
        24
    2218675712  
       2022-03-01 20:48:53 +08:00
    antd 有一个 sula 现在还是 beta 版本不完善 https://sula.vercel.app/
    FightPig
        25
    FightPig  
       2022-03-01 20:55:54 +08:00
    这写的 666 啊
    viewweiwu
        26
    viewweiwu  
    OP
       2022-03-01 21:00:23 +08:00
    @2218675712 SULA 我也关注很久了,那个确实也挺不错的。
    viewweiwu
        27
    viewweiwu  
    OP
       2022-03-01 21:01:01 +08:00
    @EscYezi 之前 Amiya 的 Dialog 弹窗组件就是显示的这句话,哈哈。
    viewweiwu
        28
    viewweiwu  
    OP
       2022-03-01 21:01:31 +08:00
    @FightPig 感谢肯定
    viewweiwu
        29
    viewweiwu  
    OP
       2022-03-01 21:01:49 +08:00
    @shanghai1998 感谢肯定
    viewweiwu
        30
    viewweiwu  
    OP
       2022-03-01 21:02:38 +08:00
    @aitaii Amiya 名字取自 《明日方舟》塔防游戏的角色
    viewweiwu
        31
    viewweiwu  
    OP
       2022-03-01 21:04:01 +08:00
    @2218675712 amis 有点面向不会技术的人使用了。Amiya 跟 Pro Components 走的路线一致,面向前端使用。
    viewweiwu
        32
    viewweiwu  
    OP
       2022-03-01 21:04:41 +08:00
    @lizhesystem 打工人就喜欢折腾😄
    pandaaa
        33
    pandaaa  
       2022-03-03 14:43:18 +08:00
    强啊楼主,给你大大的👍🏻
    viewweiwu
        34
    viewweiwu  
    OP
       2022-03-03 14:46:07 +08:00
    @pandaaa 别摸鱼了,赶紧干活儿!
    pandaaa
        35
    pandaaa  
       2022-03-03 14:53:27 +08:00
    @viewweiwu 开周会,好不容易摸会🐟
    rekulas
        36
    rekulas  
       2022-03-09 09:41:48 +08:00
    @viewweiwu 漫画模式阅读完成率高得多 参考 https://www.sohu.com/a/300039010_114877
    viewweiwu
        37
    viewweiwu  
    OP
       2022-03-09 13:42:37 +08:00
    @rekulas 这位博主我也关注了,确实挺有意思的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3613 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 82ms · UTC 04:59 · PVG 12:59 · LAX 20:59 · JFK 23:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.