zoukankan      html  css  js  c++  java
  • 利用ant-design封装react的地址输入组件

      在上一节利用element-ui封装地址输入的组件留下了个尾巴,说react搭配ant-design封装一下地址输入的组件的。本来应该早早就完成的,但是由于这中间发生了一些事情,导致了突发性的换了工作,所以一直耽误到现在,今天就把这个尾巴结束吧!

      事实上,ant-design在form组件内提供了自定义表单控件的写法,这里需要做的也就是把这个自定义表单控件搬过来而已。

      

      其实,关键在于,属性值value,和事件onChange。然后,组件内部在constructor的时候,转换传递过来的value,当Cascader的onChange事件发生时,获取新的数据值,调用this.props.onChange事件,同理,在Input组件发生onChange事件时,也是获取新的e.target.value,调用this.props.onChange事件。

      到这里,基本上这个组件封装就完成了。

      对比一下element-ui发现,两者本质上是一致的。

      都是利用内部组件各自onChange时,获取最新的值,然后调用props.onChange事件,把数值传递给使用者。很容易理解,在Cascader发生onChange时,调用props.onChange,比较不好理解的是,Input组件也是在onChange时,调用props.onChange,而不是我们通常理解的发生input时,调用props.onChange,这是为什么呢?

      不管是element-ui,还是ant-desigin,都没有向我们暴露Input组件的input事件,所以我们就没有办法获取Input组件的input事件,所以只好退而求其次的使用change事件。然后,在vue中,为了使用v-model指令,我们需要添加mode:{event: 'change', prop:'value' }属性,而在react中,没有类似的指令,都是以属性形式传递的,所以直接使用value和onChange即可。

      还是直接贴代码吧!

      

    import React, { Component } from 'react'
    import { Form, Input, Row, Col, Cascader } from 'antd'
    // 城市选择过滤函数
    function filter (inputValue, path) {
      return path.some(option => option.name.toLowerCase().indexOf(inputValue.toLowerCase()) > -1)
    }
    
    class AddressInput extends Component {
      static getDerivedStateFromProps (nextProps) {
    
        // Should be a controlled component.
        if ('value' in nextProps) {
          return {
            ...(nextProps.value || {}),
          }
        }
        return null
      }
      constructor(props) {
        super(props)
    
        const value = props.value || {}
        this.state = {
          values: value.values || [],
          registeredAddress: value.registeredAddress || '',
        }
        this.cascader = {}
      }
    
      handleAddressChange = e => {
        const registeredAddress = e.target.value || ''
        if (!('value' in this.props)) {
          this.setState({ registeredAddress })
        }
        this.triggerChange({ registeredAddress })
      }
    
      handleCascaderChange = (values, items) => {
        this.setState({ values })
        this.cascader = {
          areaCode: values.slice(-1)[0],
          areaProvince: items[0].name,
          areaCity: items[1].name,
          areaDistrict: items.slice(-1)[0].name
        }
        this.triggerChange({ values })
      }
    
      triggerChange = changedValue => {
        const onChange = this.props.onChange
        if (onChange) {
          const item = Object.assign({}, this.state, this.cascader, changedValue)
          if (item.values) delete item.values
          onChange(item)
        }
      }
    
      render () {
        const { values, registeredAddress } = this.state
        // console.log(values)
        const { allowClear = false, regionData = [], size = 'default' } = this.props
        return (
          <Row gutter={8} type="flex" justify="space-between" >
            <Col span={12}>
              <Cascader
                allowClear={allowClear}
                size={size}
                value={values}
                options={regionData}
                fieldNames={{ value: 'code', label: 'name' }}
                showSearch={{ filter }}
                onChange={this.handleCascaderChange}
                placeholder="请选择省市区" />
            </Col>
            <Col span={12}>
              <Input
                size={size}
                placeholder="请输入具体地址"
                value={registeredAddress}
                onChange={this.handleAddressChange}
              />
            </Col>
          </Row>
        )
      }
    }
    
    export default Form.create({ name: 'customized_form_controls' })(AddressInput)
    

      

      

  • 相关阅读:
    矩阵快速幂 ——(递推表达式)
    简易五子棋 V1.1.0
    自己写的五子棋
    公共子序列
    阮一峰 KMP BM算法
    「SDOI2013」森林
    「SPOJ1487」Query on a tree III
    「luogu3810」陌上花开
    「CQOI2011」动态逆序对
    「APIO2012」派遣
  • 原文地址:https://www.cnblogs.com/zhuhuoxingguang/p/11076092.html
Copyright © 2011-2022 走看看