vue el-date-picker封装及使用

使用了 Element UI 中的 el-date-picker 组件,并对其进行了进一步封装和定制

创建组件index.vue (src/common-ui/datePicker/index.vue)
vue 复制代码
<template>
  <el-date-picker
      v-model="hValue"
      ref="datePicker"
      :align="align"
      :key="poperKeyValue"
      :clear-icon="clearIcon"
      :clearable="clearable"
      :default-value="defaultValue"
      :default-time="defaultTime"
      :disabled="disabled"
      :editable="editable"
      :end-placeholder="endPlaceholder"
      :format="format"
      :name="name"
      :picker-options="pickerOptions"
      :placeholder="placeholder"
      :popper-class="poperClass"
      :prefix-icon="prefixIcon"
      :range-separator="rangeSeparator"
      :readonly="readonly"
      :size="size"
      :start-placeholder="startPlaceholder"
      :type="type"
      :unlink-panels="unlinkPanels"
      :validate-event="validateEvent"
      :value-format="valueFormat"
      @blur="handleBlur"
      @change="handleChange"
      @focus="handleFocus"
      :class="[
      clearable ? '' : 'no-close'
    ]"
  >
    <slot name="range-separator" slot="range-separator"></slot>
  </el-date-picker>
</template>

<script>
  import { mapGetters } from 'vuex'
  export default {
    name: 'HDatePicker',
    props: {
      keyValue: {
        type: String,
        default: 'datePick'
      },
      align: {
        type: String,
        validator (value) {
          return ['left', 'center', 'right'].indexOf(value) !== -1
        }
      },
      clearIcon: {
        type: String,
        default: 'el-icon-circle-close'
      },
      clearable: {
        type: Boolean,
        default: false
      },
      defaultValue: Date,
      defaultTime: {
        type: [String, Array],
        validator (value) {
          if (typeof value === 'string') {
            return true
          } else if (value instanceof Array) {
            if (value.length !== 2) {
              return false
            }
            for (let i = 0; i < value.length; i++) {
              if (typeof value[i] !== 'string') {
                return false
              }
            }
            return true
          }
          return false
        }
      },
      disabled: {
        type: Boolean,
        default: false
      },
      editable: {
        type: Boolean,
        default: false
      },
      endPlaceholder: String,
      format: String,
      name: String,
      pickerOptions: {
        type: Object,
        validator ({ disabledDate, firstDayOfWeek, onPick, shortcuts }) {
          if (disabledDate !== undefined && typeof disabledDate !== 'function') {
            return false
          }
          if (
              firstDayOfWeek !== undefined &&
              [1, 2, 3, 4, 5, 6, 7].indexOf(firstDayOfWeek) === -1
          ) {
            return false
          }
          if (onPick !== undefined && typeof onPick !== 'function') {
            return false
          }
          if (shortcuts !== undefined) {
            if (!(shortcuts instanceof Array)) {
              return false
            }
            for (let i = 0; i < shortcuts.length; i++) {
              let { text, onClick } = shortcuts[i]
              if (
                  !text ||
                  typeof text !== 'string' ||
                  !onClick ||
                  typeof onClick !== 'function'
              ) {
                return false
              }
            }
          }
          return true
        }
      },
      placeholder: String,
      popperClass: {
        type: String,
        default: 'date-picker-default'
      },
      prefixIcon: String,
      rangeSeparator: {
        type: String,
        default: () => {
          return '至'
        }
      },
      readonly: {
        type: Boolean,
        default: false
      },
      shortcuts: {
        type: Array,
        default () {
          return []
        },
        validator (value) {
          let options = [
            'today',
            'yesterday',
            'weekAgo',
            'monthAgo',
            'yearAgo',
            'lastDay',
            'lastWeek',
            'lastMonth',
            'lastYear'
          ]
          for (let i = 0; i < value.length; i++) {
            if (options.indexOf(value[i]) === -1) {
              return false
            }
          }
          return true
        }
      },
      size: {
        type: String,
        validator (value) {
          return ['medium', 'small', 'mini'].indexOf(value) !== -1
        }
      },
      startPlaceholder: String,
      type: {
        type: String,
        validator (value) {
          return (
              [
                'date',
                'daterange',
                'datetime',
                'datetimerange',
                'dates',
                'week',
                'month',
                'year',
                'monthrange'
              ].indexOf(value) !== -1
          )
        }
      },
      unlinkPanels: {
        type: Boolean,
        default: false
      },
      validateEvent: {
        type: Boolean,
        default: true
      },
      value: {
        type: [Date, String, Array],
        required: true
      },
      valueFormat: String
    },
    data () {
      return {
        hValue: '',
        clickOutsideFlag: false,
        childHandleClose: null,
        poperClass: '',
        poperKeyValue: ''
      }
    },
    created () {
      this.shortcuts.forEach(type => {
        let text
        let onClick
        if (this.type === 'date' || this.type === 'dateTime') {
          switch (type) {
            case 'today':
              text = '今天'
              onClick = function (picker) {
                picker.$emit('pick', new Date())
              }
              break
            case 'yesterday':
              text = '昨天'
              onClick = function (picker) {
                const date = new Date()
                date.setTime(date.getTime() - 3600 * 1000 * 24)
                picker.$emit('pick', date)
              }
              break
            case 'weekAgo':
              text = '一周前'
              onClick = function (picker) {
                const date = new Date()
                date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
                picker.$emit('pick', date)
              }
              break
            case 'monthAgo':
              text = '一个月前'
              onClick = function (picker) {
                const date = new Date()
                date.setTime(date.getTime() - 3600 * 1000 * 24 * 30)
                picker.$emit('pick', date)
              }
              break
            case 'yearAgo':
              text = '一年前'
              onClick = function (picker) {
                const date = new Date()
                date.setTime(date.getTime() - 3600 * 1000 * 24 * 365)
                picker.$emit('pick', date)
              }
              break
          }
        } else if (this.type === 'daterange' || this.type === 'datetimerange') {
          switch (type) {
            case 'lastDay':
              text = '最近一天'
              onClick = function (picker) {
                const end = new Date()
                const start = new Date()
                start.setTime(start.getTime() - 3600 * 1000 * 24)
                picker.$emit('pick', [start, end])
              }
              break
            case 'lastWeek':
              text = '最近一周'
              onClick = function (picker) {
                const end = new Date()
                const start = new Date()
                start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
                picker.$emit('pick', [start, end])
              }
              break
            case 'lastMonth':
              text = '最近一月'
              onClick = function (picker) {
                const end = new Date()
                const start = new Date()
                start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
                picker.$emit('pick', [start, end])
              }
              break
            case 'lastYear':
              text = '最近一年'
              onClick = function (picker) {
                const end = new Date()
                const start = new Date()
                start.setTime(start.getTime() - 3600 * 1000 * 24 * 365)
                picker.$emit('pick', [start, end])
              }
              break
          }
        }
        if (text) {
          this.pickerOptions.shortcuts.push({
            text,
            onClick
          })
        }
      })
      this.$nextTick(() => {
        if(this.$refs.datePicker) {
          this.childHandleClose = this.$refs.datePicker.handleClose
          this.$refs.datePicker.handleClose = this.handleClose
        }

      })
      this.hValue = this.value
    },
    computed: {
      ...mapGetters(['defaultTheme', 'windowWidth'])
    },
    watch: {
      value (val) {
        this.hValue = val
        this.updateInput()
      },
      hValue (val) {
        if (val === null) {
          this.hValue = ''
        }
        this.updateInput()
      },
      keyValue (val) {
        this.poperKeyValue = val

      },
      windowWidth: {
        handler (val) {
          if (this.defaultTheme == 'dark') {
            if (this.windowWidth <= 1024) {
              this.poperClass = 'date-picker-dark date-picker-dark-width'
            } else {
              this.poperClass = 'date-picker-dark'
            }
          } else {
            if (this.windowWidth <= 1024) {
              this.poperClass = 'date-picker-default date-picker-default-width'
            } else {
              this.poperClass = 'date-picker-default'
            }
          }
        },
        immediate: true,
        deep: true
      },
      poperClass: {
        handler (val) {
          this.poperKeyValue = this.keyValue + val
        },
        immediate: true
      },
      defaultTheme: {
        handler (val) {
          if (val == 'dark') {
            if (this.windowWidth <= 1024) {
              this.poperClass = 'date-picker-dark date-picker-dark-width'
            } else {
              this.poperClass = 'date-picker-dark'
            }
          } else {
            if (this.windowWidth <= 1024) {
              this.poperClass = 'date-picker-default date-picker-default-width'
            } else {
              this.poperClass = 'date-picker-default'
            }
          }
        },
        immediate: true
      }
    },
    methods: {
      handleBlur (event) {
        this.$emit('blur', event)
      },
      handleChange () {
        if (!this.clickOutsideFlag) {
          this.updateInput()
          let value = this.hValue || ''
          this.$emit('input', value)
          this.$emit('change', value)
        } else {
          this.clickOutsideFlag = false
          this.hValue = this.value
        }
      },
      handleFocus (event) {
        this.$emit('focus', event)
      },
      focus () {
        this.$refs.datePicker.focus()
      },
      handleClose () {
        if (this.$refs.datePicker.pickerVisible) {
          this.clickOutsideFlag = true
          this.childHandleClose()
        }
      },
      updateInput () {
        this.$nextTick(() => {
          if (this.$refs.datePicker.$refs.reference.$refs) {
            this.$refs.datePicker.$refs.reference.$refs.input.value = this.value
          }
        })
      }
    }
  }
</script>
<style lang="scss" scoped></style>
页面引入
  • 在需要使用HDatePicker组件的地方,通过import语句引入组件注册并使用
vue 复制代码
<template>
  <div>
    <h-date-picker
        v-model="selectedValue"
        :clearable="info.clearable"
        :start-placeholder="
              info.startPlaceholder ? info.startPlaceholder : ''
            "
        :end-placeholder="info.endPlaceholder ? info.endPlaceholder : ''"
        :placeholder="info.placeholder || ''"
        :type="info.dateType"
        :value-format="info.valueFormat"
        :prefix-icon="'el-icon-caret-bottom'"
        :disabled="info.disabled"
        :picker-options="info.pickerOptions"
    ></h-date-picker>
  </div>
</template>
<script>
  import HDatePicker from '@/common-ui/datePicker/index'

  export default {
    components: {
      HDatePicker
    },
    data() {
      return {
        info:{
          clearable: true,
          dateType:'date',
          valueFormat:'yyyy-MM-dd',
          disabled: false,
          pickerOptions:{}
        },
        dataSource: [],
        selectedValue: ''
      }
    },
    methods: {
     
    }
    // ...
  }
</script>

确保你已经安装了Vue.js和Element UI,并在项目中引入它们。

相关推荐
敲啊敲95271 分钟前
5.npm包
前端·npm·node.js
CodeClimb11 分钟前
【华为OD-E卷-木板 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
咸鱼翻面儿15 分钟前
Javascript异步,这次我真弄懂了!!!
javascript
brrdg_sefg15 分钟前
Rust 在前端基建中的使用
前端·rust·状态模式
m0_7482309440 分钟前
Rust赋能前端: 纯血前端将 Table 导出 Excel
前端·rust·excel
qq_589568101 小时前
Echarts的高级使用,动画,交互api
前端·javascript·echarts
黑客老陈2 小时前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss
正小安2 小时前
Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
前端·vite
编程百晓君2 小时前
一文解释清楚OpenHarmony面向全场景的分布式操作系统
vue.js