<template>
|
<el-date-picker
|
v-model="timeArr"
|
:type="mySetting.type"
|
:picker-options="pickerOptions"
|
:placeholder="mySetting.placeholder"
|
:range-separator="mySetting.separator"
|
:start-placeholder="mySetting.startPlaceholder"
|
:end-placeholder="mySetting.endPlaceholder"
|
:format="mySetting.format"
|
:value-format="mySetting.valueFormat"
|
:default-time="mySetting.defaultTime"
|
:align="mySetting.align"
|
:clearable="mySetting.clearable"
|
:editable="mySetting.editable"
|
:disabled="mySetting.disabled"
|
:readonly="mySetting.readonly"
|
:unlink-panels="mySetting.unLink"
|
:style="defaultStyle"
|
@change="change"
|
/>
|
</template>
|
<script>
|
/**
|
daterange 日期范围选择 (默认)
|
date 日期单选
|
datetimerange 日期时间范围选择
|
datetime 日期时间单选
|
monthrange 月份范围选择
|
*/
|
export default {
|
props: {
|
setting: {
|
type: Object,
|
default: () => {
|
return {}
|
}
|
},
|
options: {
|
type: Object,
|
default: () => {
|
return {}
|
}
|
},
|
value: {
|
// type: [Array, String],
|
required: true
|
},
|
myStyle: {
|
type: Object,
|
default: () => {
|
return {}
|
}
|
}
|
},
|
data() {
|
return {
|
timeArr: null,
|
mySetting: {
|
shortcut: true, // 使用快捷选项
|
shortcuts: [], // 使用的预设的快捷选项 (当shortcut为 true 且未自定义快捷选项时有效) 数组值为shortcutObj定义的key
|
clearable: true, // 可清空
|
editable: true, // 可编辑
|
disabled: false, // 禁用
|
readonly: false, // 只读
|
afterToday: false, // 只能选择之后的日期
|
beforeToday: false, // 只能选择之前的日期
|
unLink: true, // 取消多个日期面板的联动
|
type: 'daterange', // 类型 可选项 year/month/date/dates/ week/datetime/datetimerange/daterange/monthrange
|
format: 'yyyy-MM-dd', // 显示在输入框的格式化类型
|
valueFormat: 'yyyy-MM-dd HH:mm:ss', // 绑定值的格式化类型
|
align: 'right', // 对齐方式 可选项 left, center, right
|
placeholder: '请选择日期',
|
separator: '至', // 范围选择时的分隔符
|
startPlaceholder: '开始日期', // 范围选择时开始占位文本
|
endPlaceholder: '结束日期', // 范围选择时结束占位文本
|
defaultTime: ['00:00:00', '23:59:59'] // 范围选择时选中日期所使用的当日内具体时刻
|
},
|
pickerOptions: { // 组件配置 详情参考官网
|
shortcuts: null, // 设置快捷选项,需要传入 { text, onClick } type: Array
|
disabledDate: null, // 设置禁用状态,参数为当前日期,要求返回 Boolean type: Function
|
firstDayOfWeek: 7, // 周起始日 1 到 7 type: number
|
onPick: null // 选中日期后会执行的回调,只有当daterange或datetimerange才生效 type:Function({ maxDate, minDate })
|
},
|
defaultStyle: {} // 默认样式
|
}
|
},
|
watch: {
|
value(val) {
|
this.init(val)
|
}
|
},
|
created() {
|
this.init(this.value)
|
},
|
mounted() {
|
window.zxc = this
|
},
|
methods: {
|
/**
|
* 根据type 初始化默认配置信息
|
* @author zxc
|
* @Date 2019/7/9 11:19
|
**/
|
init(obj) {
|
/** **********************************************初始化配置信息************************************************************/
|
const type = this.setting.type || this.mySetting.type
|
switch (type) {
|
case 'datetimerange': // 日期时间范围
|
this.mySetting.format = 'yyyy-MM-dd HH:mm:ss'
|
if (obj.length > 0 && obj.every(item => item)) {
|
this.timeArr = [].concat(obj)
|
} else {
|
this.timeArr = null
|
}
|
break
|
case 'daterange': // 日期范围
|
this.mySetting.format = 'yyyy-MM-dd'
|
if (obj.length > 0 && obj.every(item => item)) {
|
this.timeArr = [].concat(obj)
|
} else {
|
this.timeArr = null
|
}
|
break
|
case 'monthrange': // 日期范围
|
this.mySetting.format = 'yyyy-MM'
|
if (obj.length > 0 && obj.every(item => item)) {
|
this.timeArr = [].concat(obj)
|
} else {
|
this.timeArr = null
|
}
|
break
|
case 'datetime':
|
this.mySetting.format = 'yyyy-MM-dd HH:mm:ss'
|
this.mySetting.defaultTime = null // 不置空会报错
|
this.timeArr = this.value
|
break
|
case 'date':
|
this.mySetting.format = 'yyyy-MM-dd'
|
this.mySetting.defaultTime = null // 不置空会报错
|
this.timeArr = this.value
|
break
|
default:
|
break
|
}
|
Object.assign(this.mySetting, this.setting)
|
Object.assign(this.defaultStyle, this.myStyle)
|
Object.assign(this.pickerOptions, this.options)
|
defaultTime = this.mySetting.defaultTime
|
/** **********************************************初始禁用项************************************************************/
|
if (this.pickerOptions.disabledDate == null) {
|
if (this.mySetting.afterToday) { // 只能选择之后的日期
|
this.pickerOptions.disabledDate = (date) => {
|
let da = new Date()
|
switch (type) {
|
case 'date':
|
case 'datetime':
|
case 'datetimerange':
|
case 'daterange':
|
da = new Date(da.getFullYear(), da.getMonth(), da.getDate())
|
break
|
case 'monthrange':
|
da = new Date(da.getFullYear(), da.getMonth())
|
break
|
}
|
return da > date
|
}
|
} else if (this.mySetting.beforeToday) { // 只能选择之前的日期
|
this.pickerOptions.disabledDate = (date) => {
|
let da = new Date()
|
switch (type) {
|
case 'date':
|
case 'datetime':
|
case 'datetimerange':
|
case 'daterange':
|
da = new Date(da.getFullYear(), da.getMonth(), da.getDate(), 23, 59, 59)
|
break
|
case 'monthrange': // 月份设置 日时分秒为 0
|
da = new Date(da.getFullYear(), da.getMonth() + 1, 0, 23, 59, 59)
|
break
|
}
|
return da < date
|
}
|
}
|
}
|
/** **********************************************初始化快捷选项************************************************************/
|
// 使用快捷选项 且 未定义选项时赋予默认值
|
if (this.mySetting.shortcut && this.pickerOptions.shortcuts == null) {
|
if (this.mySetting.shortcuts.length > 0) {
|
this.pickerOptions.shortcuts = shortcut(this.mySetting.shortcuts)
|
} else if (this.mySetting.afterToday) { // 之后日期快捷选项
|
switch (this.mySetting.type) {
|
case 'datetimerange':
|
case 'daterange':
|
this.pickerOptions.shortcuts = shortcut(['DA1W', 'DA1M', 'DA3M', 'DATYe'])
|
break
|
case 'monthrange':
|
this.pickerOptions.shortcuts = shortcut(['MTT', 'MA6M', 'MA1Y', 'MATYe'])
|
break
|
}
|
} else if (this.mySetting.beforeToday) { // 之前日期快捷选项
|
switch (this.mySetting.type) {
|
case 'datetimerange':
|
case 'daterange':
|
this.pickerOptions.shortcuts = shortcut(['DB1W', 'DB1M', 'DB3M', 'DBYbT'])
|
break
|
case 'monthrange':
|
this.pickerOptions.shortcuts = shortcut(['MTT', 'MB6M', 'MB1Y', 'MBYbT'])
|
break
|
}
|
} else { // 默认快捷选项
|
switch (this.mySetting.type) {
|
case 'datetimerange':
|
case 'daterange':
|
this.pickerOptions.shortcuts = shortcut(['DB1W', 'DB1M', 'DB3M', 'DBYbT'])
|
break
|
case 'monthrange':
|
this.pickerOptions.shortcuts = shortcut(['MTT', 'MB6M', 'MB1Y', 'MBYbT'])
|
break
|
}
|
}
|
}
|
},
|
/**
|
* 选中后的回调
|
* @author zxc
|
* @Date 2019/7/9 11:17
|
**/
|
change(val) {
|
switch (this.mySetting.type) {
|
case 'monthrange':
|
if (val == null) {
|
this.value.length = 0
|
} else {
|
// 月份结束日期设为当月最后一天 (默认为 1号)
|
const d = new Date(val[1])
|
d.setMonth(d.getMonth() + 1)
|
d.setDate(d.getDate() - 1)
|
val[1] = this.formatDate(d, this.mySetting.valueFormat)
|
for (const i in val) {
|
this.value[i] = val[i]
|
}
|
}
|
break
|
case 'datetimerange':
|
case 'daterange':
|
if (val == null) {
|
this.value.length = 0
|
} else {
|
for (const i in val) {
|
this.value[i] = val[i]
|
}
|
}
|
break
|
case 'datetime': // 须绑定change事件 | 调用 getContent 方法获取选中时间
|
break
|
}
|
console.log(val)
|
this.$emit('change', val)
|
},
|
/**
|
* 日期格式化
|
* @author zxc
|
* @Date 2019/8/28 19:17
|
**/
|
formatDate(date, fmt) {
|
try {
|
if (!(date instanceof Date)) {
|
date = new Date(date)
|
}
|
if (fmt == undefined || fmt == '') {
|
fmt = 'yyyy-MM-dd HH:mm:ss'
|
}
|
if (/(y+)/.test(fmt)) {
|
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
|
}
|
const o = {
|
'M+': date.getMonth() + 1,
|
'd+': date.getDate(),
|
'H+': date.getHours(),
|
'm+': date.getMinutes(),
|
's+': date.getSeconds()
|
}
|
for (const k in o) {
|
if (new RegExp(`(${k})`).test(fmt)) {
|
const str = o[k] + ''
|
fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? str : this.padLeftZero(str))
|
}
|
}
|
return fmt
|
} catch (e) {
|
console.log(e)
|
return '-'
|
}
|
},
|
padLeftZero(str) {
|
return ('00' + str).substr(str.length)
|
},
|
/**
|
* 获取选中日期
|
* 返回值类型与type相关 通过 this.$refs['refVal'].getContent() 调用
|
* @author zxc
|
* @Date 2019/7/9 11:18
|
**/
|
getContent() {
|
return this.timeArr
|
}
|
}
|
}
|
|
let defaultTime = null
|
/**
|
* 设置快捷选项
|
* @author zxc
|
* @Date 2019/8/28 19:18
|
**/
|
function shortcut(arr) {
|
const returnArr = []
|
for (const a of arr) {
|
if (shortcutObj[a]) {
|
returnArr.push(shortcutObj[a])
|
}
|
}
|
return returnArr.length > 0 ? returnArr : null
|
}
|
/**
|
* 设置默认时间
|
* @author zxc
|
* @Date 2019/8/28 19:17
|
**/
|
function setTime(start, end) {
|
if (Array.isArray(defaultTime)) {
|
// beginTime
|
const s = (defaultTime[0]).split(':')
|
start.setHours(Number(s[0]))
|
start.setMinutes(Number(s[1]))
|
start.setSeconds(Number(s[2]))
|
// endTime
|
const e = (defaultTime[1]).split(':')
|
end.setHours(Number(e[0]))
|
end.setMinutes(Number(e[1]))
|
end.setSeconds(Number(e[2]))
|
}
|
}
|
/**
|
* 快捷选项key命名规则:
|
* 第一位: T/D/M/Y T:时间范围选择 D:日期范围选择 M:月份范围选择 Y:年份范围选择 (暂无)
|
* 第二位: A/B/T A:该选项是之后的日期(未来) B:该选项是之前的日期(最近) T:该选项是当前的日期 (本)
|
* 第三位之后: m/H/D/W/M/Y/T m:分 H:时 D:天 W:周 M:月 Y:年 (与数字组成具体时间段) T:当前日期
|
* Wb:周初 We:周末 Mb:月初 Me:月末 Yb:年初 Ye: 年末 (搭配 T 使用)
|
* @author zxc
|
* @Date 2019/8/25 10:13
|
**/
|
const shortcutObj = {
|
'DA1W': {
|
text: '未来一周',
|
onClick: (picker) => {
|
const start = new Date()
|
const end = new Date(start)
|
end.setDate(start.getDate() + 6)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'DA1M': {
|
text: '未来一个月',
|
onClick: (picker) => {
|
const start = new Date()
|
const end = new Date(start)
|
end.setMonth(start.getMonth() + 1)
|
end.setDate(start.getDate() - 1)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'DA3M': {
|
text: '未来三个月',
|
onClick: (picker) => {
|
const start = new Date()
|
const end = new Date(start)
|
end.setMonth(start.getMonth() + 3)
|
end.setDate(start.getDate() - 1)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'DATYe': {
|
text: '今日至年末',
|
onClick: (picker) => {
|
const start = new Date()
|
const end = new Date(start.getFullYear() + 1, 0, 0)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'MTT': {
|
text: '本月',
|
onClick: (picker) => {
|
const temp = new Date()
|
const start = new Date(temp.getFullYear(), temp.getMonth(), 1)
|
const end = new Date(temp.getFullYear(), temp.getMonth(), 0)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'MA6M': {
|
text: '未来半年',
|
onClick: (picker) => {
|
const temp = new Date()
|
const start = new Date(temp.getFullYear(), temp.getMonth(), 1)
|
const end = new Date(temp.getFullYear(), temp.getMonth() + 5, 1)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'MA1Y': {
|
text: '未来一年',
|
onClick: (picker) => {
|
const temp = new Date()
|
const start = new Date(temp.getFullYear(), temp.getMonth(), 1)
|
const end = new Date(temp.getFullYear(), temp.getMonth() + 11, 1)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'MATYe': {
|
text: '本月至年末',
|
onClick: (picker) => {
|
const temp = new Date()
|
const start = new Date(temp.getFullYear(), temp.getMonth(), 1)
|
const end = new Date(temp.getFullYear(), 11, 1)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'DB1W': {
|
text: '最近一周',
|
onClick: (picker) => {
|
const end = new Date()
|
const start = new Date(end)
|
start.setDate(end.getDate() - 6)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'DB1M': {
|
text: '最近一个月',
|
onClick: (picker) => {
|
const end = new Date()
|
const start = new Date(end)
|
start.setMonth(end.getMonth() - 1)
|
start.setDate(end.getDate() + 1)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'DB3M': {
|
text: '最近三个月',
|
onClick: (picker) => {
|
const end = new Date()
|
const start = new Date(end)
|
start.setMonth(end.getMonth() - 3)
|
start.setDate(end.getDate() + 1)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'DBYbT': {
|
text: '今年至今',
|
onClick: (picker) => {
|
const end = new Date()
|
const start = new Date(end.getFullYear(), 0)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'MB6M': {
|
text: '最近半年',
|
onClick: (picker) => {
|
const temp = new Date()
|
const start = new Date(temp.getFullYear(), temp.getMonth() - 5, 1)
|
const end = new Date(temp.getFullYear(), temp.getMonth(), 0)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'MB1Y': {
|
text: '最近一年',
|
onClick: (picker) => {
|
const temp = new Date()
|
const start = new Date(temp.getFullYear(), temp.getMonth() - 11, 1)
|
const end = new Date(temp.getFullYear(), temp.getMonth(), 0)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
},
|
'MBYbT': {
|
text: '今年至今',
|
onClick: (picker) => {
|
const temp = new Date()
|
const start = new Date(temp.getFullYear(), 0, 1)
|
const end = new Date(temp.getFullYear(), temp.getMonth(), 0)
|
setTime(start, end)
|
picker.$emit('pick', [start, end])
|
}
|
}
|
}
|
</script>
|