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

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
好的,关于React Antd Cascader组件省市区级联懒加载的代码实现,我可以给你一些指导。 首先,你需要引入ReactAntd的库文件并且准备好省市区数据。假设你已经引入了ReactAntd和省市区数据,那么你可以按照以下步骤进行实现: 1. 定义一个组件,并且在组件中引入Cascader组件。 ``` import { Cascader } from 'antd'; import pcaCode from './pca-code.json'; class AreaCascader extends React.Component { render() { return ( <Cascader options={pcaCode} loadData={this.loadData} changeOnSelect placeholder="请选择地区" /> ); } } ``` 2. 实现loadData方法,该方法用于异步加载下级选项。 ``` loadData = selectedOptions => { const targetOption = selectedOptions[selectedOptions.length - 1]; targetOption.loading = true; // 模拟异步加载数据 setTimeout(() => { targetOption.loading = false; if (targetOption.children.length === 0) { targetOption.children = [ { value: '1', label: '测试1', }, { value: '2', label: '测试2', }, ]; } this.setState({ options: [...this.state.options], }); }, 1000); }; ``` 3. 将loadData方法传递给Cascader组件的loadData属性。 ``` <Cascader options={pcaCode} loadData={this.loadData} changeOnSelect placeholder="请选择地区" /> ``` 在上面的代码中,loadData方法模拟了异步加载数据,你可以根据业务需求替换成真实的异步加载方法。同时,你也可以根据需要进行样式、事件等自定义开发。 希望这些代码可以帮助到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaofei0627

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值