elementUi-时间选择器组件封装

<!-- 日期选择封装 -->
<template>
  <div class="date-input-container">
    <el-date-picker ref="dateInput"
                    v-model="inputModel"
                    style="width: 100%"
                    :type="type"
                    size="small"
                    :value-format="valueFormat"
                    format="yyyy-MM-dd HH:mm:ss"
                    unlink-panels
                    range-separator="至"
                    start-placeholder="开始日期"
                    end-placeholder="结束日期"
                    :clearable="clearable"
                    :picker-options="pickerOptions"
                    :default-time="['00:00:00', '23:59:59']"
                    @blur="timeRangeBlur"
                    @change="timeRangeChange" />
  </div>
</template>

<script>
// 这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
// 例如:import 《组件名称》 from '《组件路径》';

export default {
  // import引入的组件需要注入到对象中才能使用
  components: {},
  props: {
    value: {
      type: [Array, String],
      default: () => []
    },
    value1: {
      type: [Number, String],
      default: ''
    },
    value2: {
      type: [Number, String],
      default: ''
    },
    // pickerOptions: {
    //   type: Object,
    //   default: () => { }
    // },
    type: {
      type: String,
      default: 'datetimerange'
    },
    valueFormat: {
      type: String,
      default: 'timestamp'
    },
    clearable: {
      type: Boolean,
      default: true
    }
  },
  data () {
    // 这里存放数据
    return {
      pickerOptions: {
        shortcuts: [{
          text: '最近一周',
          onClick (picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近一个月',
          onClick (picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '最近三个月',
          onClick (picker) {
            const end = new Date()
            const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '第一季度',
          onClick (picker) {
            const end = new Date('2022-03-31 23:59:59')
            const start = new Date('2022-01-1 00:00:00')
            console.log(start, end)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '第二季度',
          onClick (picker) {
            const end = new Date('2022-06-30 23:59:59')
            const start = new Date('2022-04-1 00:00:00')
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '第三季度',
          onClick (picker) {
            const end = new Date('2022-09-30 23:59:59')
            const start = new Date('2022-07-1 00:00:00')
            picker.$emit('pick', [start, end])
          }
        }, {
          text: '第四季度',
          onClick (picker) {
            const end = new Date('2022-12-31 23:59:59')
            const start = new Date('2022-10-1 00:00:00')
            picker.$emit('pick', [start, end])
          }
        }]
      },
      inputModel: this.value,
      input1: null,
      input2: null,
      changeFlag: 2, // 0:第一个输入框改变 1:第二个输入框改变 2:日期选择模式(默认)
      inputValue1: this.value[0],
      inputValue2: this.value[1],
      inputValue_copy: null,
      tempValue: this.value
    }
  },
  // 监听属性 类似于data概念

  computed: {
  },
  // 监控data中的数据变化
  watch: {
    value (n, o) { // n为新值,o为旧值;
      this.inputModel = n
    },
    value1 () {
      this.changeValue()
    }
  },
  // 生命周期 - 创建完成(可以访问当前this实例)
  created () {
    if ((!this.value || this.value.length === 0) && this.value1 && this.value2) {
      this.value = [this.value1, this.value2]
    }
  },
  // 生命周期 - 挂载完成(可以访问DOM元素)
  mounted () {
    this.input1 = document.querySelector('.date-input-container').querySelectorAll('input')[0]
    this.input2 = document.querySelector('.date-input-container').querySelectorAll('input')[1]
    let _this = this
    this.input1.addEventListener('keydown', function (e) {
      _this.inputValue_copy = _this.input1.value
    }, false)

    this.input2.addEventListener('keydown', function (e) {
      _this.inputValue_copy = _this.input2.value
    }, false)

    this.input1.addEventListener('keyup', function (e) {
      let keyCode = e.keyCode || e.which
      _this.dealFormatFun(this, 0, keyCode)
    }, false)

    this.input2.addEventListener('keyup', function (e) {
      let keyCode = e.keyCode || e.which
      _this.dealFormatFun(this, 1, keyCode)
    }, false)
  },
  // 方法集合
  methods: {
    setParentModeVal (value) {
      this.$emit('update:value', value)
      this.changeFlag = 2 // 恢复默认模式
      this.$emit('timeChange', value)
    },

    dealFormatFun ($this, flag, keyCode) {
      this.changeFlag = flag
      keyCode = keyCode >= 96 && keyCode <= 105 ? keyCode - 48 : keyCode
      let inputDom = flag === 0 ? this.input1 : this.input2
      var pos
      // ---------- 获取当前光标位置 ---------------
      if ($this.setSelectionRange) {
        // 标准浏览器
        pos = $this.selectionStart
      } else {
        // IE浏览器
        var selectStart
        var selectEnd
        var selectText
        var emptyValue = -1
        var range = document.selection.createRange()
        selectText = range.text
        range.moveStart('character', -$this.value.length)
        pos = range.text.length
        selectStart = pos - (selectText.length)
        selectEnd = selectStart + (selectText.length)

        if (selectStart !== selectEnd) {
          pos = emptyValue
        } else {
          selectStart = emptyValue
          selectEnd = emptyValue
        }
      }

      // ---------- 处理输入结果及光标位 ---------------
      if (keyCode >= 48 && keyCode <= 57) { // 仅能输入数字
        if (inputDom.value.length > 19) {
          let month = Number(inputDom.value.substring(5, 7))
          let month_flag = [1, 3, 5, 7, 8, 10, 12].indexOf(month) > -1
          let month_first = Number(inputDom.value.substring(5, 6))
          let day_first = Number(inputDom.value.substring(8, 9))
          let hour_first = Number(inputDom.value.substring(12, 13))
          // 处理月份(十位大于1、个位大于2)、天数(十位大于3、十位为3时个位大于1)、小时(十位大于2、十位为2个位大于3)、分钟及秒(十位大于5)时的格式问题
          if ((pos === 6 && keyCode > 49) || (pos === 7 && month_first === 1 && keyCode > 50) || (pos === 9 && keyCode > 51) || (pos === 10 && day_first === 3 && ((month_flag && keyCode > 49) || (!month_flag && keyCode > 48))) || (pos === 12 && keyCode > 50) || (pos === 13 && hour_first === 2 && keyCode > 51) || ((pos === 15 || pos === 18) && keyCode > 53)) {
            inputDom.value = inputDom.value.substring(0, pos - 1) + inputDom.value.substring(pos, inputDom.value.length)

            inputDom.value = this.replaceStr(inputDom.value, 4, '-')
            inputDom.value = this.replaceStr(inputDom.value, 7, '-')
            inputDom.value = this.replaceStr(inputDom.value, 10, ' ')
            inputDom.value = this.replaceStr(inputDom.value, 13, ':')
            inputDom.value = this.replaceStr(inputDom.value, 16, ':')

            // ---------- 重置光标位置 ---------------
            // pos 光标的位置 -1为最后一位
            if (pos < 0) pos = inputDom.value.length
            if ($this.setSelectionRange) {
              // 兼容火狐,谷歌
              setTimeout(() => {
                $this.setSelectionRange(pos - 1, pos - 1)
                inputDom.focus()
              }, 0)
            } else if ($this.createTextRange) {
              // 兼容IE
              var rng = $this.createTextRange()
              rng.move('character', pos - 1)
              rng.select()
            }
          } else {
            // 若输入的为数字 则执行替换操作
            inputDom.value = inputDom.value.substring(0, pos) + inputDom.value.substring(pos + 1, inputDom.value.length)

            let substr = inputDom.value.substring(pos, pos + 1)
            if (substr === '-' || substr === ' ' || substr === ':') {
              pos++
            }

            if (inputDom.value.length >= 20) {
              inputDom.value = inputDom.value.substring(0, 19)
            }

            inputDom.value = this.replaceStr(inputDom.value, 4, '-')
            inputDom.value = this.replaceStr(inputDom.value, 7, '-')
            inputDom.value = this.replaceStr(inputDom.value, 10, ' ')
            inputDom.value = this.replaceStr(inputDom.value, 13, ':')
            inputDom.value = this.replaceStr(inputDom.value, 16, ':')

            if (pos === 6 && keyCode === 49) { // 处理月份
              let month_late = Number(inputDom.value.substring(pos, pos + 1))
              if (month_late > 2) {
                inputDom.value = this.replaceStr(inputDom.value, pos, '2')
              }
            }

            if (pos === 9 && keyCode === 51) { // 处理天数
              let day_late = Number(inputDom.value.substring(pos, pos + 1))
              if (day_late > 2) {
                if ([1, 3, 5, 7, 8, 10, 12].indexOf(Number(inputDom.value.substring(5, 7))) > -1) {
                  inputDom.value = this.replaceStr(inputDom.value, pos, '1')
                } else {
                  inputDom.value = this.replaceStr(inputDom.value, pos, '0')
                }
              }
            }

            if (pos === 12 && keyCode === 50) { // 处理小时
              let hour_late = Number(inputDom.value.substring(pos, pos + 1))
              if (hour_late > 3) {
                inputDom.value = this.replaceStr(inputDom.value, pos, '3')
              }
            }

            // ---------- 重置光标位置 ---------------
            // pos 光标的位置 -1为最后一位
            if (pos < 0) pos = inputDom.value.length
            if ($this.setSelectionRange) {
              // 兼容火狐,谷歌
              setTimeout(() => {
                $this.setSelectionRange(pos, pos)
                inputDom.focus()
              }, 0)
            } else if ($this.createTextRange) {
              // 兼容IE
              rng = $this.createTextRange()
              rng.move('character', pos)
              rng.select()
            }
          }
        }
      } else {
        // 若为非数字且不是"左移"、"右移"操作 则执行删除操作
        if (keyCode !== 37 && keyCode !== 39) {
          inputDom.value = inputDom.value.substring(0, pos - 1) + inputDom.value.substring(pos, inputDom.value.length)
          // ---------- 重置光标位置 ---------------
          // pos 光标的位置 -1为最后一位
          if (pos < 0) pos = inputDom.value.length
          if ($this.setSelectionRange) {
            // 兼容火狐,谷歌
            setTimeout(() => {
              $this.setSelectionRange(pos - 1, pos - 1)
              inputDom.focus()
            }, 0)
          } else if ($this.createTextRange) {
            // 兼容IE
            rng = $this.createTextRange()
            rng.move('character', pos - 1)
            rng.select()
          }
        }
      }

      if (flag === 0) {
        this.inputValue1 = (new Date(inputDom.value).getTime()) || (new Date().getTime())
      } else {
        this.inputValue2 = (new Date(inputDom.value).getTime()) || (new Date().getTime())
      }
      if (this.inputValue1 > this.inputValue2) {
        this.inputValue2 = this.inputValue1
      }
      // this.inputModel = [this.inputValue1, this.inputValue2]
    },

    replaceStr (str, index, char) {
      return str.substring(0, index) + char + str.substring(index + 1)
    },
    changeValue () {
      if (!this.value1 || !this.value2) {
        this.inputModel = []
      } else if (this.value1 > this.value2) {
        this.inputModel = []
      } else {
        this.inputModel = [this.value1, this.value2]
      }
    },
    timeRangeChange (value) {
      console.log(value)
      let value1, value2
      if (value && value.length > 0) {
        value1 = value[0]
        if (this.valueFormat === 'timestamp' && this.type === 'daterange') {
          value2 = value[1] // + (3600 * 24 * 1000) - 1
          // value2 = value[1] - 1
        } else {
          value2 = value[1]
        }
        this.setParentModeVal([this.inputValue1, this.inputValue2])
      } else {
        value1 = null
        value2 = null
        this.setParentModeVal([])
      }
      if (this.changeFlag === 2) {
        this.inputValue2 = value2
        this.inputValue1 = value1
      }
      this.$emit('update:value1', value1)
      this.$emit('update:value2', value2)
    },
    clear () {
      this.inputModel = []

    },

    timeRangeBlur () {
      this.inputModel = [this.inputValue1, this.inputValue2]
      this.setParentModeVal([this.inputValue1, this.inputValue2])
    }
  }
}
</script>
<style rel='stylesheet/scss' lang='scss' scoped>
.date-input-container {
  width: 100%;

  .el-date-editor--datetimerange.el-input__inner {
    width: 100%;
  }
}
</style>

2使用

     <span class="date-editor">

          <DateInput ref="recharge"

                     :value.sync="timeRange"

                     @timeChange="timeRangeChange" />

        </span>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值