react结合antd的Cascader组件实现pc端选择城市控件

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.效果及拿到的值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39953537/article/details/94130234
今日推荐