自学内容网 自学内容网

el-date-picker 自定义指令,输入数字自动转换显示yyyy-mm-dd格式


在main.js引入自定义指令direct.js

import '@/components/common/js/direct.js'

direct.js

公共部分

注:自定义指令传值时,binding.value是接收值

import Vue from 'vue'
// import $ from 'jquery'; // 在需要使用的页面中

// 日期转换正则
const convertYMDRegExp = function (value) {
  // 判断输入的时间为几位数,正则匹配相应的事件格式。可直接采用moment转换,更直接。
  value = value.replace(/[^0-9]/g, '')
  if (value.length > 5 && value.length < 9) {
    value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3') // 格式化输入格式,2021-03-01
  } else if (value.length > 9 && value.length < 13) {
    value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3 $4:$5') // 格式化输入格式,2021-03-01 09:50
  } else if (value.length > 12) {
    value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3 $4:$5:$6') // 格式化输入格式,2020-03-01 09:50:30
  } else {
    return ''
  }
  value = supplement(value)
  const time = value && value.constructor == String ? value : ''  // 转换时间格式
  return time
}

// 补0
// 使用$&匹配
function supplement(str) {
  // replace第一个参数正则
  // (?<=\/|-|\.|:|\b)\d{1}  用的是后顾,查找 / 或者 - 或者 . 或者 : 或者 单词边界 或者 T 后面的一个数字
  // \d{1}(?=\/|-|\.|:|\b)   用的是前瞻,查找 / 或者 - 或者 . 或者 : 或者 单词边界  或者 T 前面的一个数字
  // replace 第二个参数"0$&" 匹配到的字符串前置补0
  // return str.replace(/(?<=\/|-|\.|:|\b|T)\d{1}(?=\/|-|\.|:|\b|T)/g, "0$&");
  let regExp = new RegExp("(?<=\/|-|\\.|\:|\\b|T)\\d{1}(?=\/|-|\\.|\:|\\b|T)", "g")
  return str.replace(regExp, "0$&");
}

时间日期控件,表格内编辑时间控件可用 - (年-月-日)

<el-table-column prop="time" label="时间" width="140">
<template slot-scope="scope">
<el-date-picker v-if="!!scope.row.addNew || !!scope.row.editRow" :size="elTableTreeFormSize" v-model="scope.row.time" type="date" v-tableYMDFormat value-format="yyyy-MM-dd" @keypress.enter.native="saveRow(scope.row)"></el-date-picker>
<span v-else>{{ scope.row.time }}</span>
</template>
</el-table-column>
// 第一种(和时间范围控件相同)
Vue.directive('tableYMDFormat', {
  inserted: function (el, binding, vnode) {
    el.addEventListener('change', () => {
      let value = $($(el).children('input')[0]).val()
      const time = convertYMDRegExp(value);
      vnode.child.$emit('input', time);
    });
  }
});
// 第二种
Vue.directive('tableYMDFormat', {
  inserted: function (el, binding, vnode) {
    const { context: _this } = vnode
    if (_this && _this._isVue) {
      const $this = $($(el).children('input')[0])
      $this.on('change', function () {
        let value = $this.val()
        const time = convertYMDRegExp(value);
        vnode.child.$emit('input', time);
      })
    }
  }
});

时间范围控件 - (年-月-日)

<el-date-picker v-model="DateArr" type="daterange" v-daterangeYMDFormat value-format="yyyy-MM-dd" range-separator="" start-placeholder="开始" end-placeholder="结束"></el-date-picker>
Vue.directive('daterangeYMDFormat', {
  inserted: function (el, binding, vnode) {
    // 绑定 change 事件来更新绑定的数组
    el.addEventListener('change', () => {
      let value = []
      value[0] = $($(el).children('input')[0]).val()
      value[1] = $($(el).children('input')[1]).val()
      // const value = [$($(el).children('input')[0]).val(), $($(el).children('input')[1]).val()]
      const time = value.map(date => convertYMDRegExp(date))
      vnode.child.$emit('input', time);
    });
  }
});

日期转换主要正则

value = value.replace(/[^0-9]/g, '')

年-月-日/年-月-日 时:分/年-月-日 时:分:秒

if (value.length > 5 && value.length < 9) {
  value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3') // 年-月-日,2021-03-12
} else if (value.length > 9 && value.length < 13) {
  value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3 $4:$5') // 年-月-日 时:分,2021-03-12 09:50
} else if (value.length > 12) {
  value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3 $4:$5:$6') // 年-月-日 时:分:秒,2020-03-12 09:50:30
} else {
  return ''
}

年-月

// 年-月
if (value.length === 5) {
  value = value.replace(/^(\d{4})\D*(\d{1})\D*/, '$1-0$2') // 格式化输入格式,2021-03
} else if (value.length > 5) {
  value = value.replace(/^(\d{4})\D*(\d{1,2})\D*/, '$1-$2') // 格式化输入格式,2021-03
} 

年-月-01/年-01-01

手动补齐'01'

// 年-月-01/
if (value.length > 5 && value.length < 7) { 
  value = value + '01'
}
// 年-01-01
if (value.length <= 4) { 
  value = value + '0101'
} else if (value.length > 4) {
  value = value.substring(0, 4) + '0101'
}
value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3') // 格式化输入格式

时间日期选择器 - (年-月-日)

 <el-form-item ref="birthday" prop="birthday">
<el-date-picker v-model="birthday" type="date" v-dateYMDFormat value-format="yyyy-MM-dd"> </el-date-picker>
</el-form-item>
Vue.directive('dateYMDFormat', {
  inserted: function (el, binding, vnode) {
    const { value: _obj } = binding
    const { context: _this, data } = vnode
    const { expression: key } = data.model
    let arr = []
    const modelValue = function (value, len) {
      // 判断输入的时间为几位数,正则匹配相应的事件格式。可直接采用moment转换,更直接。
      value = value.replace(/[^0-9]/g, '')
      if (value.length > 5 && value.length < 9) {
        value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3') // 格式化输入格式,2021-03-01
      } else if (value.length > 9 && value.length < 13) {
        value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3 $4:$5') // 格式化输入格式,2021-03-01 09:50
      } else if (value.length > 12) {
        value = value.replace(/^(\d{4})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*(\d{1,2})\D*/, '$1-$2-$3 $4:$5:$6') // 格式化输入格式,2020-03-01 09:50:30
      } else {
        return false
      }
      value = supplement(value)
      // const newValue = value.replace(/-/g,"/"); // 解决前台new Date(yyyy-MM-dd)转化时间相差8小时的问题,不知道靠不靠谱,改用moment
      // const time = value && value.constructor == String ? new Date(newValue) : value  // 转换时间格式
      // const time = value && value.constructor == String ? moment(value) : value  // 转换时间格式
      // const time = value  // 转换时间格式
      const time = value && value.constructor == String ? value : ''  // 转换时间格式
      let keys = key.split('.')
      if (arr.length === len) {
        arr = [];
      }
      arr.push(time)
      // 判断指令是否有传值,是否有传数组的名称跟索引值,原因:转换出来的时间控件_this[key1][key2]取不到绑定的相关值
      if (!_obj) {
        // 处理简单的绑定
        if (keys && keys.length >= 2) {
          const [key1, key2, key3, key4] = keys
          if (key4) {
            _this[key1][key2][key3][key4] = len === 2 ? arr : time;
          } else if (key3) {
            _this[key1][key2][key3] = len === 2 ? arr : time;
          } else {
            _this[key1][key2] = len === 2 ? arr : time;
          }
        } else {
          _this[key] = len === 2 ? arr : time;
        }
      } else {
        // 处理循环中的时间控件绑定,需要传值,再去相应的数组中查找相应的字段赋值
        let objKey = _obj.obj.split('.')
        if (objKey && objKey.length >= 2) {
          // 解构赋值
          const [flag1, flag2, flag3, flag4] = objKey;
          // _obj.index:索引,_obj.modelName:绑定的字段名
          if (flag4) {
            _this[flag1][flag2][flag3][flag4][_obj.index][_obj.modelName] = len === 2 ? arr : time;
          } else if (flag3) {
            _this[flag1][flag2][flag3][_obj.index][_obj.modelName] = len === 2 ? arr : time;
          } else {
            _this[flag1][flag2][_obj.index][_obj.modelName] = len === 2 ? arr : time;
          }
        } else {
          _this[objKey][_obj.modelName] = len === 2 ? arr : time;
        }
      }
    };
    if (_this && _this._isVue) {
      const $this = $($(el).children('input')[0])
      const $this2 = $($(el).children('input')[1])
      // 判断是范围的还是单个独立的日期时间控件,范围的两个输入框都要绑定change事件
      if ($(el).children('input').length > 1) {
        $this.on('change', function () {
          let value = $this.val()
          modelValue(value, 2);
        })
        $this2.on('change', function () {
          let value = $this2.val()
          modelValue(value, 2);
        })
      } else {
        $this.on('change', function () {
          let value = $this.val()
          modelValue(value, 1);
        })
      }
    }
  }
})


原文地址:https://blog.csdn.net/weixin_45665171/article/details/142794090

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!