基于react-vant封装表单基本常用组件
react-vant 组件库地址
目录
一、基础组件
1. LocationPicker
效果演示:

组件代码
import React, {useEffect, useRef, useState} from 'react';
import {Cell, Empty, Loading, Picker, Popup} from "react-vant";
import PropType from "prop-types";
import '@/common/style/common.less'
import emptyPic from '@/common/images/empty.png'
import {_arrayFilterEmpty, _isEmpty} from "../../../common/js/utils";
/**
* 默认值
*/
LocationPicker.defaultProps = {
isLoaded: false,
columns: [],
defaultValues: [],
}
/**
* 类型和必填校验
*/
LocationPicker.propTypes = {
defaultValues: PropType.array.isRequired,
isLoaded: PropType.bool.isRequired
}
function LocationPicker(props) {
//数据源
const columns = props.columns;
//是否必填
const required = props.required;
//数据是否已加载
const isLoaded = props.isLoaded;
//默认展示数据
const defaultValues = props.defaultValues;
//组件数据变化函数
const onLineChange = props.onLineChange;
const [showPopup, setShowPopup] = useState(false);
const [lineValue, setLineValue] = useState('');
const picker = useRef(null);
/**
* 选中值
* @param val
* @returns {*[]}
*/
const handleSelected = (val) => {
if (val.constructor !== Array) {
console.error('选中数据格式错误,请处理')
}
let textList = []
let codeList = []
val.forEach((el) => {
textList.push(el['text'])
codeList.push(el['value'])
})
textList = _arrayFilterEmpty(textList);
codeList = _arrayFilterEmpty(codeList);
//展示数据
setLineValue(textList.join('-'))
//向父组件传递数据
onLineChange(textList, codeList)
}
/**
* 设置默认选中
* @param defaultArr
*/
const setDefaultValues = (defaultArr) => {
picker && picker.current && picker.current.setValues(defaultArr)
};
/**
* 弹出pop
* @returns {Promise<void>}
*/
const showPickerPop = async () => {
await setShowPopup(true)
setDefaultValues(defaultValues)
}
/**
* 隐藏pop
* @returns {Promise<void>}
*/
const hidePickerPop = async () => {
await setShowPopup(false)
}
/**
* 监听默认值变化
*/
useEffect(() => {
setLineValue(defaultValues.join('-'))
}, [defaultValues]);
return (
<div>
<Cell title="地址" isLink size="large" value={lineValue} required={required} onClick={() =>
showPickerPop()
}/>
<Popup
visible={showPopup}
position="bottom"
style={{height: '45%'}}
safeAreaInsetBottom
onClose={() => setShowPopup(false)}
>
{!isLoaded && <Loading type="ball" className='content-loading' vertical>加载中...</Loading>}
{
isLoaded && columns.length <= 0 &&
<Empty
className="custom-image"
image={emptyPic}
description="暂无数据"
/>
}
{
isLoaded && columns.length > 0 &&
<Picker
columns={columns}
ref={picker}
onConfirm={async (val) => {
handleSelected(val);
await hidePickerPop();
}}
onCancel={async (val) => {
handleSelected([]);
await hidePickerPop();
}}
/>
}
</Popup>
</div>
);
}
export default LocationPicker;
页面state 设置:
//线路基础数据
const [columns,setColumns] = useState([]);
const [isLineLoaded, setLineLoaded] = useState(false);
//当前选择的线路lineList 线路编码lineCodeList
const [lineList, setLineList] = useState([]);
const [lineCodeList, setLineCodeList] = useState([]);
useEffect(() => {
setTimeout(async () => {
await setLineLoaded(true)
await setColumns( [
{
"text": '江苏',
"children": [
{
"text": '苏州',
"children": [
{
"text": '姑苏区',
value: "001"
},
{
"text": '吴中区'
}
]
},
{
"text": '扬州',
"children": [
{
"text": '广陵区'
},
{
"text": '邗江区'
}
]
}
]
},
{
"text": '浙江',
value: "002",
"children": [
{
"text": '杭州',
"children": [
{
"text": '西湖区'
},
{
"text": '余杭区'
}
]
},
{
"text": '温州',
"children": [
"",
{
"text": '鹿城区'
},
{
"text": '瓯海区'
}
]
}
]
}
])
}, 5000)
}, [])
组件引用
<LocationPicker
required
columns={columns}
defaultValues={lineList}
isLoaded={isLineLoaded}
onLineChange={(valArr, codeArr) => {
setLineList(valArr);
setLineCodeList(codeArr)
}}/>
总结
每天记录一点,从小小菜鸟变小菜鸟!!!