最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 使用ant design vue封装一个日期组件,提交数据为字符串——dateStingPicker

    正文概述 掘金(heyhaiyang)   2021-03-14   1077

    dateStingPicker组件封装

    演示实例

    使用ant design vue封装一个日期组件,提交数据为字符串——dateStingPicker

    序——使用软件及框架版本

    1. vue 2.6.11
    2. ant-design-vue 1.7.1
    3. moment.js(日期转换依赖)

    设计思路

    1. 根据需求,可以知道需要回显格式需要为“XXXX年XX月XX日”,查看组件库a-date-picker,了解到format属性可以将在输入框中数据转换为特定格式。
    2. 在提交数据时,由于我们是封装组件,给其他页面中使用,所以需要将需要提交的值由子组件置到父组件上,所以在日期组件中选中日期出发的事件change/input,在选中日期的时候需要使用到$emit,将值置到上层副组件。
    3. 在回显数据时,查看页面数据的时候,表单上显示数据,此时从后台数据中拿到的是字符串“20210314”,同时需要将数据格式化为“XXXX年XX月XX日”,显示在输入框中。

    具体代码过程

    1. template模板区域

    <template>
      <div>
        <!--  这里momVal是momentValue的缩写,因为value的真实值是moment对象  -->
        <a-date-picker
          :value="momVal"
          :allowClear="allowClear"
          :disabled="disabled"
          :format="dateFormat"
          :mode="mode"
          :placeholder="placeholder"
          @change="dateChanged"
        >
        </a-date-picker>
      </div>
    </template>
    

    在这里用到几个属性,

    1. 由于是封装组件,所以使用value实现数据的双向绑定,在表单中使用allClear的时候在点击清除按钮时也可以清除表单显示和底层数据。
    2. mode是输入框显示模式,date、month、year可选,但是year模式时不太好用,具体可以参考下一篇,year年份组件封装。
    3. 当然组件上不止有@change事件,@blur@select都是可以使用的,可以根据项目需求来具体使用,不过在父组件上使用事件时,需要在子组件props 中声明,并在模板部分使用双向绑定:select="select"

    2. js区域

    <script>
    import moment from 'moment'
    
    export default {
      name: 'dateStringPicker',
      props: {
        value: {
          type: [String, Number],
          default: ''
        },
        // 返回的日期格式
        dateFormat: {
          type: String,
          default: 'YYYY年MM月DD日'
        },
        // 类型,选择年份请传入"year",选择年月请传入"month"
        mode: {
          type: String,
          default: 'date'
        },
        placeholder: {
          type: String,
          default: '请选择日期'
        },
        disabled: {
          type: Boolean,
          default: false
        },
        allowClear: {
          type: Boolean,
          default: true
        },
        // 判断输入的两种状态input/change
        triggerChange: {
          type: Boolean,
          default: true
        }
      },
      data () {
        const dateStr = this.value
        return {
          // 由于vue是数据驱动页面加载的,所以在data中需要给value一个初始值
          momVal: !dateStr ? null : moment(dateStr, this.dateFormat),
          lastValue: ''
        }
      },
      watch: {
        // 此处的监听,用来实现设计思路3
        value (val) {
          if (!val) {
            this.momVal = null
          } else {
            this.momVal = moment(val, 'YYYYMMDD')
          }
        }
      },
      methods: {
        moment,
        // 此处change事件,用来实现设计思路2,此处有注意事项,当时写的时候还是遇到一些问题的
        dateChanged (mom) {
          // 参考注意事项3
          if (!mom) {
            if (this.triggerChange) {
              this.$emit('change', null)
            } else {
              this.$emit('input', null)
            }
          } else {
            // 参考注意事项1
            this.lastValue = moment(mom).format('YYYYMMDD')
            // 参考注意事项2
            if (this.triggerChange) {
              this.$emit('change', this.lastValue
            } else {
              this.$emit('input', this.lastValue)
            }
          }
        }
      }
    }
    </script>
    

    注意事项:

    1. 在提交数据的时候需要提交给表单的数据我们通过lastValue传递;如果不需要格式转换可以直接使用this.momVal = value这样传递的数据类型还是moment对象。

    2. 生造一个triggerChange属性的原因是,在ant-design-vue组件中,使用a-form表单组件的时候,分了两种情况

      • 提交数据时不需要校验规则,使用v-model绑定数据
      • 提交数据时需要校验规则,使用v-decorator

      在使用v-model时,点击日期触发的事件时input,而在使用v-decorator时,点击日期触发的事件时change

    3. 为什么要在提交数据的change 事件中,添加一个!mom的条件判断,原因是:在表单上添加allClear属性之后,表单中会出现可以清除当前输入框数据的符号“❌”,在清除表单数据的时候,表单上回显示no valid或者NaN,原因可能是清除之后表单的初始值数据类型不对,这点我也不是太清楚。总之,解决方法就是添加一个!mom的条件判断,在清除表单数据的时候重新给表单value赋一个空值null,因为value的类型是对象,所以不能是""

    测试demo实例

    <template>
      <div>
        <div class="box">
          <h1>this is dateStringPiker</h1>
          <div class="btn">
            <a-button type="primary" @click="click"> 提交数据</a-button>
          </div>
          <a-form :form="editForm" layout="inline">
            <!--  使用v-model时,是以input事件从子组件抛出value值  -->
            <a-form-item label="v-model形式的绑定的 日期">
              <date-string-picker
                v-model="editForm.date"
                :trigger-change="false">
              </date-string-picker>
            </a-form-item>
    
            <!-- 在需要校验的情况下,在表单中使用v-decorator的形式绑定,
            同时自组件要以change的形式将value抛出到上层副组件 -->
            <!--        <a-form-item label="v-decorator形式绑定的 日期">-->
            <!--          <date-string-picker-->
            <!--            v-decorator="['date',{initialValue:''}]"-->
            <!--            :trigger-change="true">-->
            <!--          </date-string-picker>-->
            <!--        </a-form-item>-->
          </a-form>
        </div>
      </div>
    </template>
    
    <script>
    import dateStringPicker from '@/component/dateStringPicker'
    
    export default {
      name: 'demo',
      components: {
        dateStringPicker
      },
      data() {
        return {
          // 使用v-decorator要使用下面方法注册form表单
          // editForm: this.$form.createForm(this)
    
          // v-model的形式,form表单注册则比较简单
          editForm: {
            date: ''
          }
        }
      },
      methods: {
        click() {
          console.log('点击按钮')
          // v-model绑定测试提交
          // console.log(this.editForm)
    
          // v-decorator绑定,测试数据提交
          this.editForm.validateFields((err, value) => {
            console.log(err)
            console.log(value)
          })
        }
      }
    }
    </script>
    
    <style scoped lang="less">
    .box {
      margin: 30px 30px;
    }
    
    .btn {
      margin: 30px 30px;
    }
    </style>
    
    

    Find me

    Gitee:gitee.com/heyhaiyon/a…

    微信公众号:heyhaiyang

    掘金:heyhaiyang

    博客园:heyhaiyang

    头条号:heyhaiyang


    起源地下载网 » 使用ant design vue封装一个日期组件,提交数据为字符串——dateStingPicker

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元