React combinado con el componente Cascader de antd para realizar el control de la ciudad de selección del lado de la PC

React combinado con el componente Cascader de antd para realizar el control de la ciudad de selección del lado de la PC

Necesidades comerciales, busqué mucho en línea y descubrí que no estaban satisfechas, así que escribí una.

1. La implementación es la siguiente

Consejo:
haga clic en la dirección de datos https://xf-1252186245.cos.ap-chengdu.myqcloud.com/data/data.js para copiarlo y colocarlo en el directorio del mismo nivel del componente y asígnele el nombre data.js.

Si la dirección data.js anterior está distorsionada, haga clic en la dirección del almacén de github https://github.com/lxf/react-city-select para clonar el código localmente, hay data.js en el código fuente, o puede acceder directamente a la dirección del almacén de github de data.js Camino .

Dependencia: reaccionar antd rc-form prop-types, etc., primero instale las dependencias, se omiten los pasos.

Archivo 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. Utilice

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. El efecto y el valor obtenido
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_39953537/article/details/94130234
Recomendado
Clasificación