0.1.28 • Published 3 years ago
@kne/react-filter v0.1.28
react-filter
描述
筛选器
安装
npm i --save @kne/react-filter概述
用户列表数据的筛选
默认提供了常见的几种筛选项
支持自定义筛选项类型扩展
示例(全屏)
示例代码
- 基础示例
 - 展示一个筛选器的普通模式
 - reactFilter(@kne/react-filter),(@kne/react-filter/dist/index.css),message(antd/lib/message),_(lodash)
 
const {useState} = React;
const {default: Filter, createExtraButton} = reactFilter;
const {default: antdMessage} = message;
const {City, List, Range, Text, Selector, Check, DateTime} = Filter.type;
const {isNumber} = _;
const BaseExample = () => {
    const [value, setValue] = useState({});
    console.log(value);
    return <Filter value={value} onChange={(value) => {
        setValue(value);
    }} more={[
        <Text label="测试字段" name="test1"/>,
        <Text label="测试字段2" name="test2" onBeforeSearch={(value) => {
            antdMessage.error(`提交被拦截,输入值${value}`);
            return false;
        }}/>,
        <Text.Number label="测试字段7" name="test7"/>,
        <Range label="测试字段3" name="test3"/>,
        <Selector label="测试字段4" name="test4"
                  options={[{
                      label: "英语", value: "en"
                  }, {
                      label: "日语", value: "jap"
                  }, {
                      label: "法语", value: "fac"
                  }]}/>,
        <DateTime label="测试字段5" name="test5" showTime/>,
        <DateTime.Range label="测试字段6" name="test6"/>
    ]} list={[[<City label="目前城市" name="currentCity" size={5}/>], [<List label="学历" name="degree" size={2}>
        <List.Item value="0" label="初中"/>
        <List.Item value="1" label="高中"/>
        <List.Item value="2" label="大学专科"/>
        <List.Item value="3" label="大学本科"/>
    </List>], [<List label="求职意向" name="yixiang" size={1}
                     options={[{label: "暂时不找工作", value: 0}, {label: "在职看机会", value: 1}, {
                         label: "离职正在找工作", value: 2
                     }]}/>], [<Range label="年龄" name="age" template={(value) => {
        if (!value || value.length === 0) {
            return "";
        }
        if (!isNumber(value[0]) && isNumber(value[1])) {
            return `${value[1]}岁以下`;
        }
        if (!isNumber(value[1]) && isNumber(value[0])) {
            return `${value[0]}岁以上`;
        }
        return `${value[0]}-${value[1]}岁`;
    }}/>, <Text label="行业" name="inter"/>, <Selector label="语言" name="lang"
                                                     options={[{
                                                         label: "英语", value: "en"
                                                     }, {
                                                         label: "日语", value: "jap"
                                                     }, {
                                                         label: "法语", value: "fac"
                                                     }]}/>], [<List size={1}
                                                                    label="薪资范围"
                                                                    name="sarl"
                                                                    options={[{
                                                                        label: "10k以下", value: [null, 10]
                                                                    }, {
                                                                        label: "10k-20k", value: [10, 20]
                                                                    }, {
                                                                        label: "20k以上", value: [20, null]
                                                                    }]}
                                                                    more={createExtraButton({
                                                                        type: "range", template: (value) => {
                                                                            if (!value || value.length === 0) {
                                                                                return "";
                                                                            }
                                                                            if (!isNumber(value[0]) && isNumber(value[1])) {
                                                                                return `${value[1]}k以下`;
                                                                            }
                                                                            if (!isNumber(value[1]) && isNumber(value[0])) {
                                                                                return `${value[0]}k以上`;
                                                                            }
                                                                            return `${value[0]}k-${value[1]}k`;
                                                                        }
                                                                    })}/>, <Check label="海外经历" name="out"/>]]}/>;
};
render(<BaseExample/>);- 简单示例
 - 展示一个简单的筛选项,一般放在列表页title extra位置
 - reactFilter(@kne/react-filter),(@kne/react-filter/dist/index.css),space(antd/lib/space)
 
const {useState} = React;
const {default: Filter} = reactFilter;
const {default: Space} = space;
const {RadioList, Selector, Text, CheckboxList} = Filter.type;
const Example = () => {
    const [value, setValue] = useState([]);
    const [radioValue, setRadioValue] = useState({});
    const [checkboxValue, setCheckboxValue] = useState({});
    console.log(value, radioValue, checkboxValue);
    return <Space direction="vertical">
        <Filter value={value} onChange={setValue} labelHidden itemLabelHidden list={[[
            <Text name="positionName" label="职位名称"/>,
            <Selector name="type" options={[
                {
                    label: '全职',
                    value: 1
                }, {
                    label: '兼职',
                    value: 2
                }
            ]} label="职位类型"/>
        ]]}/>
        <Filter value={radioValue} onChange={setRadioValue} labelHidden list={[[
            <RadioList name="state" label="客户状态" options={[
                {
                    label: "全部状态",
                    value: 0
                }, {
                    label: "待开发",
                    value: 1
                }, {
                    label: "开发中",
                    value: 2
                }, {
                    label: "已签约",
                    value: 3
                }, {
                    label: "已终止",
                    value: 4
                }
            ]}/>
        ]]}/>
        <Filter value={checkboxValue} onChange={setCheckboxValue} labelHidden list={[[
            <CheckboxList name="state" label="客户状态" options={[
                {
                    label: "全部状态",
                    value: 0
                }, {
                    label: "待开发",
                    value: 1
                }, {
                    label: "开发中",
                    value: 2
                }, {
                    label: "已签约",
                    value: 3
                }, {
                    label: "已终止",
                    value: 4
                }
            ]}/>
        ]]}/>
    </Space>
};
render(<Example/>);- 扩展示例
 - 展示扩展筛选项,自定义筛选项
 - reactFilter(@kne/react-filter),modal(antd/lib/modal),input(antd/lib/input),space(antd/lib/space),datePicker(antd/lib/date-picker),monment(moment),_(lodash),(@kne/react-filter/dist/index.css)
 
const {default: ReactFilter, useFilterContext, FilterItem, withFilterItem, SearchButton} = reactFilter;
const {default: Modal} = modal;
const {default: Input} = input;
const {default: Space} = space;
const {default: DatePicker} = datePicker;
const {useRef, useState} = React;
const {get} = _;
const MyFilter = (props) => {
    const ref = useRef();
    const {value, onChange} = useFilterContext();
    return <FilterItem {...props} onClick={() => {
        Modal.confirm({
            icon: null,
            content: <Input ref={ref} defaultValue={get(value[props.name], 'value')}/>,
            onOk: () => {
                const value = ref.current.input.value;
                onChange(props.name, {
                    label: value,
                    value
                });
            }
        });
        console.log(value);
    }}/>;
};
const DateRange = withFilterItem(({
                                      name,
                                      size,
                                      isMore,
                                      defaultActive,
                                      onBlur,
                                      onSearch,
                                      onBeforeSearch,
                                      startProps,
                                      endProps,
                                      placeholder
                                  }) => {
    const ref = useRef();
    const sort = (a, b) => {
        if (a && b) {
            return new Date(a) - new Date(b);
        }
        return 0;
    };
    return <SearchButton size={size} template={(value) => {
        if (!value[0] && value[1]) {
            return `${value[1]}之前`;
        }
        if (!value[1] && value[0]) {
            return `${value[0]}之后`;
        }
        return value.join('~');
    }} isMore={isMore} onBlur={onBlur} defaultActive={defaultActive}
                         name={name}
                         onSearch={onSearch}
                         onBeforeSearch={onBeforeSearch}>
        {({value, setValue, setActive}) => {
            return <div ref={ref}>
                <Space>
                    <DatePicker size="small" {...startProps} getPopupContainer={() => ref.current}
                                value={get(value, 0) && monment(get(value, 0))}
                                onChange={(inputValue) => {
                                    const target = [inputValue && inputValue.format('YYYY-MM-DD HH:mm:ss'), get(value, 1)];
                                    setValue(target.sort(sort));
                                }} onFocus={() => {
                        setActive(true);
                    }} placeholder={Array.isArray(placeholder) ? placeholder[0] : (placeholder || "请输入")}/>
                    ~
                    <DatePicker size="small" {...endProps} getPopupContainer={() => ref.current}
                                value={get(value, 1) && monment(get(value, 1))}
                                onChange={(inputValue) => {
                                    const target = [get(value, 0), inputValue && inputValue.format('YYYY-MM-DD HH:mm:ss')];
                                    setValue(target.sort(sort));
                                }} onFocus={() => {
                        setActive(true);
                    }} placeholder={Array.isArray(placeholder) ? placeholder[0] : (placeholder || "请输入")}/>
                </Space>
            </div>
        }}
    </SearchButton>
});
const Example = () => {
    const [value, setValue] = useState({});
    return <ReactFilter value={value} onChange={setValue} moreTrigger="click"
                        more={[<MyFilter name="test1" label="测试"/>, <DateRange name="test2" label="测试2"/>]}/>
};
render(<Example/>);API
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| value | 筛选器的值,该组件为一个受控组件 | object | - | 
| onChange | 筛选器的值发生改变的时候调用的函数 | function | - | 
| list | 筛选器的选项,为一个二维数组,二维数组中的每一个数组为一行,内部数组的每一项为一个筛选选项,筛选选项为Filter.type中的一项或者是自行扩展的选项 | array | [] | 
| more | 筛选项更多选项,为一个一维数组,数组中的每一项为一个筛选项,和list不同的是该筛选项默认为收起状态 | array | [] | 
| moreLabel | 更多选项的label | string | 更多 | 
| moreTrigger | 更多选项的触发方式,默认为hover触发,页可以设置为click | string | hover | 
| label | 筛选器的label | string | 筛选项 | 
| labelHidden | 筛选器的label及筛选内容行是否隐藏 | boolean | false | 
| itemLabelHidden | 筛选项的label是否隐藏 | boolean | false | 
| unfoldText | 展开提示文字 | string | 展开 | 
| foldText | 收起提示文字 | string | 收起 | 
| displayLine | 默认展开行数 | number | 2 | 
| defaultDisplay | 默认是否展开 | boolean | false | 
| isExtra | 是否将list切分成收起项和默认展开项 | boolean | true | 
| extra | 额外内容 | boolean | null | 
Filter.type
City(城市选择), List(列表选择,可以多选或者单选), Range(数据范围), Text(文字输入) Text.Number, Selector(下拉选项), Check(单项选择), RadioList(单选列表), CheckboxList(多选列表)
DateTime(时间选择),DateTime.Time DateTime.Range DateTime.Week DateTime.Month DateTime.Year
公共参数
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| label | 筛选项名称 | string | - | 
| name | 筛选项的key | string | - | 
| placeholder | 筛选项的placeholder(如果可以显示的话),如果不传值通常会去label的值 | string | - | 
Text|Text.Number|Range
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| onBeforeSearch | 带有确定按钮的筛选项,在点击确定后会调用该方法,如果该方法返回为false,则该选项的值不会被提交给筛选项 | function | - | 
Range|DateTime.Range
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| template | 将一组数据范围显示成一段用户可阅读的问题的模版,参数为筛选项的值,要求返回一个描述的字符串 | function | - | 
| placeholder | 当为字符串时前后两个输入框显示同样内容,当为一个数组时,第一个输入框显示数组的第一个值,第二个输入框显示为数组的第二个值 | string|array | - | 
Range
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| startProps | 该参数会结构以后传给第一个InputNumber | object | - | 
| endProps | 该参数会结构以后传给第二个InputNumber | object | - | 
List
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| children | 筛选项的每一项的值,必须为 List.Item,也可以为一个render function可以接收到参数render({value,onChange}) | List.Item|function | - | 
| size | 最大可以选中数量,等于1的时候为单选,操作逻辑和多选略有不同 | number | 2 | 
| options | 筛选项,为一个数组,每一项的值为{label,value}该属性有值优先取该值忽略children | array | - | 
List.Item
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| value | 筛选项的值 | - | - | 
| label | 筛选项显示项 | string | - | 
SearchButton
用于自行封装过滤选项时的工具组件。Text,Text.Number,Range使用该组件实现。该组件可以让筛选项有一个包裹层在鼠标经过时显示,同时有一个确定按钮,在确定按钮点击时筛选项的结果会提交到Filter。
| 属性名 | 说明 | 类型 | 默认值 | 
|---|---|---|---|
| defaultActive | 默认是否激活活跃状态 | boolean | false | 
| defaultValue | 默认值通常不需要传,会取筛选器的对应项的值 | - | - | 
| buttonText | 确认按钮的文案 | string | 确定 | 
| template | 格式化结果函数 | function | - | 
| children | 是一个函数,需要传一个render函数返回内层的输入组件,会接收到children({value, setValue, setActive})参数 | function | - | 
| onBlur | 会模拟一个失去焦点的事件,点击该组件区域外的地方会触发并执行该函数 | function | - | 
| onSearch | 点击确认按钮时触发函数 | function | - | 
| onBeforeSearch | 点击确认按钮会先触发该函数如果该函数显示返回false值则不会再触发onSearch函数,用于再筛选项的值提交给筛选器之前的数据验证 | function | - | 
| onActiveChange | 激活状态改变时触发函数 | function | - | 
其他参数参考对应内部组件的参数
0.1.14
3 years ago
0.1.15
3 years ago
0.1.27
3 years ago
0.1.28
3 years ago
0.1.20
3 years ago
0.1.21
3 years ago
0.1.22
3 years ago
0.1.23
3 years ago
0.1.24
3 years ago
0.1.25
3 years ago
0.1.26
3 years ago
0.1.16
3 years ago
0.1.17
3 years ago
0.1.18
3 years ago
0.1.19
3 years ago
0.1.10
4 years ago
0.1.11
4 years ago
0.1.12
4 years ago
0.1.13
4 years ago
0.1.9
4 years ago
0.1.8
4 years ago
0.1.7
4 years ago
0.1.6
4 years ago
0.1.5
4 years ago
0.1.4
4 years ago
0.1.3
4 years ago
0.1.2
4 years ago
0.1.1
4 years ago
0.1.0
4 years ago