x-antd
v0.1.1
Published
基于 antd 封装的一些后台业务的常见组件
Downloads
2
Readme
本组件库基于 antd design,封装了一系列后台开发的常用组件以及一些常用的工具函数。
目前封装的组件有:
布局类:Menu(导航菜单),Breadcrumb(面包屑导航),Loading(全局 Loading);
表单类:AutoInput(异步自动完成选择框),Cascader(异步级联选择框),DateRange(日期选择框),NumberRange(数字范围输入框),ImgUpload(图片上传器),Eidtor(富文本编辑器),FormItem(常用 FormItem)
其他:Thumb(缩略图)
使用:
npm i x-antd -S
import 'x-antd/dist/index.css'
布局类
Menu(导航菜单)
import { Menu } from 'x-antd'
const routes = [
{
name: '首页',
path: '/home',
icon: 'home',
routes: [
{
name: '子页',
path: '/home/sub-page'
}
]
}
]
<Menu
routes={routes}
title={() =>
<div>
<Icon component={<img src="logo.png" />} />
<span>管理后台</span>
<div>
}
/>
核心接受一个 routes 注册表,routes 要遵循上述格式;它会根据当前路由自动进行展开和高亮;其他 api 和 antd Menu 保持一致;如果要支持收缩,title 要遵循上述格式,这样收缩时会把文字隐藏,只展示图标,如果不需要收缩,可以随意。
Breadcrumb(面包屑导航)
import { Breadcrumb } from 'x-antd'
import { Breadcrumb as AntBreadcrumb } from 'antd'
const { Item } = AntBreadcrumb
<Breadcrumb routes={routes}>
<Item>扩展条目</Item>
</Breadcrumb>
核心接受一个 routes 注册表,routes 格式和 Menu 保持一致,该面包屑组件会根据路由变化自动生成对应的面包屑导航;有些子页面不在路由里,比如详情页,可以在 children 里手动添加,children 必须为 antd Breadcrumb Item 组件。
Loading(全局 loading 组件)
immport { connect } from 'react-redux'
import { Loading } from 'x-antd'
const Layout = ({ loading }) =>
<div>
...
<Loading loading={loading} />
</div>
export default connect(({ loading }) => ({ loading }))(Layout)
全局 loading 组件,为一个透明遮罩+一个 loading 的 Icon,浮在最上层;后台项目通常在 http 层设置 redux 里 loading 的值,这样组件内只用写业务逻辑,无需处理任何 loading 的问题;
表单类
所有表单类控件都按照 antd From 自定义控件的规范写的,可以在 Form 里按常规表单控件使用;如果不再表单里使用,可以使用 value 和 onChange 进行赋值和取值。
AutoInput(异步自动完成框)
import { AutoInput } from 'x-antd'
// 在antd form表单下使用
<From.Item label="水果">
{getFieldDecorator('fruits')(<AutoInput fetch={getCates} />)}
</From.Item>
// 非表单下,使用onChange取值
<AutoInput fetch={getFruits} onChange={val => console.log(val)} />
const getFruits = keyword => Promise.resolve({'id1': '苹果', 'id2': '香蕉', 'id2': '橘子'})
核心是接受一个 fetch 的函数,这个函数需要接受以一个关键词(用户输入值)为参数,异步返回一个 json;组件内做了 300ms 的防抖。
Cascader(异步级联选择框)
import { Cascader } from 'x-antd'
<From.Item label="类目">
{getFieldDecorator('categroies')(<Cascader fetch={getCates} />)}
</From.Item>
const getCates = fatherId => Promise.resolve([{value: 'id123', label: '蔬菜类', isLeaf: false}])
核心是接受一个 fetch 的函数,这个函数需要接受以一个上一级的 value(第一级不传)为参数,返回一个上述格式的数组。isLeaf 的意思是是否为叶节点(没有下一级)
DateRange(日期选择框)
import { DateRange } from 'x-antd'
<From.Item label="起止时间">
{getFieldDecorator('date')(<DateRange />)}
</From.Item>
antd 有自己 RangePicker 组件,之所以还要再写,是因为 antd 的 RangePicker 不能只选一个值,这个可以只选一端。返回值遵循 antd 规范,为一个数组,里面是两个 moment 对象 [moment, moment]
NumberRange(数字范围输入框)
import { NumberRange } from 'x-antd'
<From.Item label="折扣">
{getFieldDecorator('discount')(<Number min={0.01} max={1} precision={2} step={0.01} />)}
</From.Item>
主要是做了一个好看的样式,api 和 antd InputNumber 保持一致;自动转换,当最小值小于最大值会自动转换,不用写校验逻辑;
ImgUpload(图片上传)
import { ImgUpload } from 'x-antd'
<From.Item label="图片">
{getFieldDecorator('pics', {
initialValue: [{uid: 1, url: '1.img'}, {uid: 2, url: '2.img'},]
})(<ImgUpload max={10} actiton="upload.com" />)}
</From.Item>
默认值的格式要遵循上述格式(因为 antd 要做动画,所以需要一个 uid), max 代表最大可上传图片数,基于 antd Upload 组件,其他 api 保持一致。
注意,如果你不是在 Form 里使用,onChange 获取到值以后你需要拿这个值去 setState,然后再从 state 里去取值,因为 antd 是渲染缩略图之后才开始上传,所以必须用 setState 去触发 render,否则图片会一直是 uploading 状态,得不到后端返回的 response, 详见 antd 的这个 issue: https://github.com/ant-design/ant-design/issues/2423
VerifyCode(手机验证码组件)
import { VerfiyCode } from 'x-antd'
<From.Item label="验证码">
{getFieldDecorator('code')(<VerfiyCode send={api.sendCode} />)}
</From.Item>
核心接受一个 send 的函数,用于调用发送验证码接口,内部主要封装了倒计时的逻辑和成功消息提示;
Editor(富文本编辑器)
基于 tinymce,使用的时候要在 html 头部引入 tinymce 源文件
<script src="https://cdn.jsdelivr.net/npm/[email protected]/tinymce.min.js"></script>
import { Editor } from 'x-antd'
<From.Item label="详情">
{getFieldDecorator('detail')(<Editor init={{
image_upload_url: 'http://upload.com',
image_upload_response_formater: res => res.fileUrl
}}/>)}
</From.Item>
已经做了本地化处理,init 为 tinymce 官方的 init,如需做个性化设置,请参照官方文档。上传图片:接受一对参数,image_upload_url 为上传地址;image_upload_response_formater 为转换函数,需要返回上传成功的图片的 url,why? 因为后端返回的 url 的字段名是不确定的,所以需要传一个 formatter 函数。
FormItem(表单 Item)
import { FormItem } from 'x-antd'
const { Select } = FormItem
<Select label="类型" formkey="type" options={{1: '类型1', 2: '类型2', 3: '类型3'}} {...this.props.form} >
这不是功能性组件,只是为了书写方便,会生成一个 Form.Item 包含的下拉框组件,并在顶部加上了“全部”选项;why? 这种类型的数据通常在搜索表单和数据列表都会用到,所以抽出为一个 json 然后分别传值会比较方便, 基本用于搜索表单。
其他
Thumb(缩略图组件)
import { Thumb } from 'x-antd'
<Thumb src="img.png" style={{width: 120, height: 80}}/>
通过 style 来控制缩略图外框尺寸,图片会等比例剧中展示,多出的地方以黑边填充,类似微信;src 可以不传,这时展示“暂无图片”。
工具函数
格式化(放在 utils/format 下)
clearObject
import { clearObject } from 'x-antd/utils/format'
clearObject({ a: 1, b: null, c: undefined, d: 0, e: '' }) // -> {a: 1, d: 0}
表单提交的时候通常有些值是未填的,需要把它们过滤掉, 过滤的值包括 undefined, null, '';
toYuan
import { toYuan } from 'x-antd/utils/format'
toYuan(123) // -> 1.23
const columns = [
{
title: '价格',
dataIndex: 'price',
render: toYuan,
},
]
把金额由后台传来的分转换为元并保留两位小数,表格里使用比较方便。
dateString
import { dateString } from 'x-antd/utils/format'
const columns = [
{
title: '日期',
dataIndex: 'date',
render: dateString,
},
]
可以把后台传来日期字符串,时间戳等转换为公司要求的标准格式,如果不需要时分秒,dateString(val, false)。
如果有什么常用组件还未封装,大家提出来,一起封装。