vue - vue中对Vant日历组件(calendar)的二次封装
vue中对Vant日历组件(calendar)的二次封装
·
vue中对vant日历选择器组件实现的的二次封装;主要实现功能如下:
主要功能:
- 日期区间选择(基本);
- 自定义选择器的底部按钮,添加清除时间操作(slot插槽);
- 指定默认选中的日期范围(当前日期到本月底通过default-date)
- 自定义日期可选范围;(通过 min-date 和 max-date )
- 支持默认值的传入;(没有默认值时会显示placeholder:请选择时间区间)
- 自定义组件的宽度;(通过props:Width,推荐使用百分比 如:80%)
效果图如下:
日期区间组件实现如下:calendar.vue
主要代码讲解:
1, 通过
<template slot="footer">
可以更改底部默认的按钮,我这边添加来了一个清除时间
的按钮;点击清除时间
按钮会把时间清空,恢复到默认状态;
2,通过min-date 和 max-date
控制日期可以选择的开始和结束的范围;
3,通过default-date
可以更改指定默认选中的日期范围,需要注意的是返回的是一个数组,开始位置和结束位置;可以看一下timeInterval()方法;
4,点击确认按钮onConfirmAll()会把所选择开始日期和结束日期返回给父组件;时间格式如下:2023-02-20
;
5,可以传入defaultData 默认值,没有默认值会显示:请选择时间区间
;
6,可以传入:Width="'100%'"
来控制组件的宽度;
7,针对不同的业务需求可以对当前组件做出相应的调整;
<template>
<!-- 日期选择组件 可指定选择范围 -->
<div class="calendar" :style="`width:${Width}`">
<van-field :label="title" v-model="date" right-icon="arrow-down" readonly @click="show = true" :placeholder="placeholder" />
<!-- 日期选择器 -->
<van-calendar safe-area-inset-bottom v-model="show" color="#1989fa" type="range" @confirm="onConfirm" :min-date="minDate" :max-date="maxDate" :default-date="timeInterval()" ref="myCalendar">
<template slot="footer">
<div class="footer">
<van-button @click="clearTimeAll" type="danger" class="footerBtn">清除时间</van-button>
<van-button class="footerBtn" @click="onConfirmAll" type="info">确认</van-button>
</div>
</template>
</van-calendar>
</div>
</template>
<script>
export default {
name: 'calendar',
components: {},
props: {
/* 可以不用传 用来展示左侧的文案 为空则不展示文案*/
title: {
type: String,
default: '',
},
/* 传过来的默认值 */
defaultData: {
type: String,
// default:'请选择'
},
placeholder: {
type: String,
default: '请选择时间区间',
},
// 宽度
Width: {
type: String,
},
},
data() {
return {
date: this.defaultData ? this.defaultData : '', // 先判断有没有默认值 有就用没有就为空
show: false,
// 日期区间
minDate: new Date(2022, 0, 1),
maxDate: new Date(2025, 12, 31),
// 当前日期
currentDate: new Date().getDate(),
};
},
computed: {},
watch: {
// 监听到需要重新赋值
defaultData(newValue) {
this.date = newValue;
},
},
created() {
// 处理默认值 如果有默认值直接赋值
if (this.defaultData) {
this.date = this.defaultData;
}
},
mounted() {},
methods: {
/* 日期区间 当前自动选择的日期区间 :取当天到月底 返回的是一个数组*/
timeInterval() {
let new_year = new Date().getFullYear();
let new_month = new Date().getMonth() + 1;
let new_date = new Date(new_year, new_month, 1); //取当年当月中的第一天
let end = new Date(new_date.getTime() - 1000 * 60 * 60 * 24); //取最后一天
return [new Date(), end];
},
/* 确认选择 组件自带的事件 */
onConfirm(date) {
const [start, end] = date;
this.show = false;
this.date = `${this.formatDate(start)} - ${this.formatDate(end)}`;
// 传给父组件 以此来请求数据
this.$emit('dateFun', `${this.formatDate(start)}`, `${this.formatDate(end)}`);
},
/* 确认按钮 */
onConfirmAll() {
// 直接调用上面的方法
if (this.$refs.myCalendar) {
this.$refs.myCalendar.onConfirm();
} else {
console.warn('myCalendar实例没有获取到');
}
},
/* 清除时间 时间置空*/
clearTimeAll() {
this.date = '';
this.show = false;
this.$emit('dateFun', ``, ``);
},
/* 转换时间 */
formatDate(date) {
// 给日期补0
return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
},
},
};
</script>
<style scoped lang="scss">
// 覆盖 van-field的样式
/deep/ .van-cell {
padding: 2px 5px;
border-radius: 5px;
border: 1px solid #1457f0;
}
/deep/ .van-field__right-icon {
margin-right: 0;
padding: 0;
color: #1457f0;
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
// 底部自定义按钮的样式
.footerBtn {
width: 150px;
border-radius: 2px;
}
}
</style>
父组件中使用:
<template>
<div>
<!-- 日期区间选择器演示 -->
<h4>Vant日期区间选择器封装</h4>
<div class="Calendar">
<Calendar @dateFun="dateFun" :Width="'80%'" :defaultData="defaultData"></Calendar>
</div>
</div>
</template>
<script>
// 时间选择器
import Calendar from '../../components/calendar/calendar.vue';
export default {
//注册
components: { Calendar },
data() {
return {
// 组件的默认值 没有可以为空 或者 组件中不在使用defaultData属性
defaultData:'2023-01-01-2023-02-01',
],
};
},
methods: {
//接收子组件传过来的日期值
dateFun(start, end) {
console.log('start:', start, 'end:', end);
// 保存获取到的时间...
},
},
};
</script>
<style scoped lang="scss">
.Calendar {
margin-top: 20px;
}
</style>
更多推荐
已为社区贡献16条内容
所有评论(0)