react结合antd的Cascader组件实现pc端选择城市控件
业务需求,网上找了好多,发现都不太满意,于是自己写了一个
1.实现如下
提示:
数据地址点击 https://xf-1252186245.cos.ap-chengdu.myqcloud.com/data/data.js 复制下来放到组件同级目录,命名data.js就好。
上面地址data.js乱码的话,点击 github仓库地址 https://github.com/l-x-f/react-city-select 将代码克隆到本地,源码里有data.js,也可以直接访问 data.js github仓库地址路径。
依赖: react antd rc-form prop-types等, 先安装依赖,步骤略。
CitySelect.jsx 文件
import React, {
Component } from "react";
import {
createForm } from "rc-form";
import {
Cascader } from "antd";
import city from "./data"; // 数据见上提示
import PropTypes from "prop-types";
//先配置修饰器 没有配置的话用把 @createForm()删掉
//然后把最后一行 export default CitySelect; 换成 export default createForm()(CitySelect)
@createForm()
class CitySelect extends Component {
// props类型检查
static propTypes = {
// 监听选择
onChange: PropTypes.func,
// 获取选择值
getSelectedValues: PropTypes.func,
// 默认值
value: PropTypes.array
};
onCascaderChange = selectedValues => {
const {
onChange, getSelectedValues } = this.props;
const result = [];
// 递归查询城市所有数据
function findCityData(city) {
city.forEach(item => {
const {
id, label, value, children } = item;
if (selectedValues.includes(value)) {
result.push({
id, label, value });
}
if (children && children.length) {
findCityData(children);
}
});
}
findCityData(city);
// 分发监听
onChange && onChange(selectedValues);
getSelectedValues && getSelectedValues(result);
};
componentDidMount() {
const {
form: {
setFieldsValue },
value: selectedValues
} = this.props;
if (!selectedValues || !selectedValues.length) {
return;
}
const result = [];
// 递归查询城市名称数据
function findLabel(children) {
children.forEach(item => {
const {
label, value, children } = item;
if (selectedValues.includes(label)) {
result.push(value);
}
if (children && children.length) {
findLabel(children);
}
});
}
// 卡省份解决县或市名称一样的问题
city.forEach(item => {
const {
label, value, children } = item;
if (selectedValues.includes(label)) {
result.push(value);
if (children && children.length) {
findLabel(children);
}
}
});
// 设置默认值
setFieldsValue({
city: result });
}
render() {
const {
getFieldProps } = this.props.form;
return (
<div>
<Cascader
options={
city}
{
...getFieldProps("city", {
onChange: this.onCascaderChange,
rules: [{
required: true }]
})}
placeholder="请选择城市"
/>
</div>
);
}
}
export default CitySelect;
2.使用
import React, {
Component } from "react";
import {
Form, Button, message, Icon } from "antd";
import CitySelect from "@/components/CitySelect";
import "./hotel.less";
const FormCreate = Form.create;
const FormItem = Form.Item;
@FormCreate()
class HotelSetting extends Component {
state = {
selectedValues: []
};
handleReset = () => {
this.props.form.resetFields();
};
// 获取选择值
getSelectedValues = selectedValues => {
this.setState({
selectedValues
});
};
handleSumit = e => {
const {
form } = this.props;
e.preventDefault();
form.validateFields((err, formData) => {
console.log(formData, "formData");
if (err) {
message.destroy();
return message.warning("请完整填写表单");
}
const data = {
...formData,
selectedValues: this.state.selectedValues
};
console.log(data, "data");
});
};
render() {
const {
getFieldDecorator } = this.props.form;
const defaultCity = ["陕西省", "西安市", "碑林区"];
return (
<Form
className="custom-form custom-vertical-hotel-form"
layout="vertical"
labelAlign="left"
onSubmit={
e => {
this.handleSumit(e);
}}
style={
{
background: "#fff", padding: 24 }}
>
{
/* 数据绑定 拿到的city字段是城市编码 getSelectedValues监听可以拿到选择的数据对象 */}
<FormItem label="城市选择:">
{
getFieldDecorator("city", {
initialValue: defaultCity,
rules: [{
required: true, message: "请选择城市选择" }]
})(<CitySelect getSelectedValues={
this.getSelectedValues} />)}
</FormItem>
<FormItem label="城市选择:">
<CitySelect
getSelectedValues={
this.getSelectedValues}
value={
defaultCity}
/>
</FormItem>
<FormItem style={
{
paddingBottom: 0 }}>
<Button type="primary" htmlType="submit">
<Icon type="arrow-up" />
保存
</Button>
</FormItem>
</Form>
);
}
}
export default HotelSetting;
hotel.less
:global(.custom-vertical-hotel-form .ant-form-item-label) {
width: 90px;
vertical-align: top;
}
:global(.custom-vertical-hotel-form .ant-form-item-control-wrapper) {
width: 340px;
display: inline-block;
}
3.效果及拿到的值