赞
踩
在做h5移动端app时,因业务需要,要做按日区间选择开始和结束日期,按月区间选择开始和结束月份,ui组件中有按日区间选择的,没有按月区间选择,所以结合业务自己写了一个。
- <template>
- <van-action-sheet
- v-model="showDate"
- position="bottom"
- @close="closeCalendar"
- title="选择月份"
- round
- :style="{ height: '80%' }"
- ref="monthDate"
- >
- <ul class="content">
- <li v-for="(item, index) in years" :key="index" v-scroll>
- <div class="monthTitle">{{ item.year }}年</div>
- <van-row>
- <van-col
- span="6"
- v-for="(childItem, key) in item.children"
- :key="key"
- :class="childItem.monthClass"
- >
- <div
- class="monthList"
- @click="selectList(item, childItem)"
- :class="childItem.isSelect === true ? 'isSelect' : ''"
- >
- <div :class="childItem.disabledMonth == true ? 'isDisabled' : ''">
- {{ childItem.month }}月
- </div>
- <div
- class="startEnd"
- :class="
- childItem.text == '开始' || childItem.text == '结束'
- ? 'fontSize'
- : ''
- "
- >
- {{ childItem.text }}
- </div>
- </div>
- </van-col>
- </van-row>
- </li>
- </ul>
- <div class="footBtn" default="footer">
- <div class="footBox">
- <van-button @click="onReset" type="primary">重 置</van-button>
- <van-button @click="onConfirm" type="primary">确 定</van-button>
- </div>
- </div>
- </van-action-sheet>
- </template>
-
- <script>
- import { Toast } from "vant";
- export default {
- props: {
- isAllowSameDay: {
- type: Boolean,
- },
- calendarshow: {
- type: Boolean,
- },
- yearLength: {
- type: Number,
- },
- defaultDate: {
- type: Array,
- required: true,
- },
- },
- data () {
- return {
- years: [],
- monthList: [
- "一",
- "二",
- "三",
- "四",
- "五",
- "六",
- "七",
- "八",
- "九",
- "十",
- "十一",
- "十二",
- ],
- showDate: this.calendarshow,
- selectArr: [],
- currentYear: new Date().getFullYear(), //当前年份
- currentMonth: new Date().getMonth() + 1, //当前月份
- startDefaultYear: new Date().getFullYear(), //开始年份
- startDefaultMonth: new Date().getMonth() + 1, //开始月份
- endDefaultYear: new Date().getFullYear(), //结束年份
- endDefaultMonth: new Date().getMonth() + 1, //结束月份
- startText: "开始",
- endText: "结束",
- startEndText: "开始/结束"
- };
- },
- directives: {
- // 自定义指令 月历定位到当前年份
- scroll: {
- inserted (el) {
- el.scrollIntoView();
- },
- },
- },
- watch: {
- calendarshow (val) {
- this.showDate = val; //显示隐藏月历
- },
- defaultDate (val) {
- this.startDefaultYear = val[0].getFullYear(); //开始年份
- this.startDefaultMonth = val[0].getMonth() + 1; //开始月份
- this.endDefaultYear = val[1].getFullYear(); //结束年份
- this.endDefaultMonth = val[1].getMonth() + 1; //结束月份
- this.setDefaultMonth();
- },
- },
- created () {
- this.initCalendar()
- },
- methods: {
- // 初始化月历
- initCalendar () {
- const that = this;
- for (let i = 1; i <= that.yearLength; i++) {
- const item = {
- year: that.currentYear - (that.yearLength - i),
- children: [],
- };
- for (let j = 0; j < that.monthList.length; j++) {
- let list = {
- month: that.monthList[j],
- isSelect: false,
- value: j + 1,
- text: "",
- };
- // 判断当前月之后的月份不可选
- if ((item.year == that.currentYear && j + 1 > that.currentMonth) || (item.year == that.currentYear - (that.yearLength - 1) && j + 1 < that.currentMonth)) {
- list.disabledMonth = true;
- } else {
- list.disabledMonth = false;
- }
- item.children.push(list);
- }
- that.years.push(item);
- }
- },
- // 设置默认值
- setDefaultMonth () {
- const that = this;
- const startYear = that.startDefaultYear; //默认开始年份
- const endYear = that.endDefaultYear; //默认结束年份
- const startMonth = that.startDefaultMonth; //默认开始的年份
- const endMonth = that.endDefaultMonth; //默认开始的年份
- that.selectArr = [];
- that.years.map((item) => {
- item.children.map((list) => {
- list.text = "";
- list.isSelect = false;
- // 当前起始年份、月份都相同
- if (startYear == endYear && startMonth == endMonth) {
- list.monthClass = "";
- if (item.year == startYear && list.value == startMonth) {
- list.text = that.startEndText;
- list.isSelect = true;
- that.monthSaveArr(startYear, startMonth, list.text);
- }
- } else {
- // 起始年份相同、月份不同
- if (item.year == startYear && list.value == startMonth) {
- list.text = that.startText;
- list.isSelect = true;
- that.monthSaveArr(item.year, list.value, list.text);
- }
- if (item.year == endYear && list.value == endMonth) {
- list.text = that.endText;
- list.isSelect = true;
- that.monthSaveArr(item.year, list.value, list.text);
- }
- }
- });
- });
- },
- // 选择的月份存入一个数组中
- monthSaveArr (year, month, text) {
- const dataItem = {
- year: year,
- month: month,
- text: text
- };
- this.selectArr.push(dataItem);
- },
- // 选择月份
- selectList (item, childItem) {
- const that = this;
- const selectStartYear = that.selectArr[0].year; //选择开始的年份
- const selectStartMonth = that.selectArr[0].month;//选择开始的月份
- // 大于当前月份不可选
- if (childItem.disabledMonth == true) {
- return;
- }
- // 开始月份 (如果数组为空 或者 已经选了开始结束月份为同一月) 选择开始月份
- if (that.selectArr.length == 0 || that.selectArr[0].text == that.startEndText) {
- that.cancelSelectMonth();
- childItem.text = that.startText;
- that.monthSaveArr(item.year, childItem.value, childItem.text);
- } else if (that.selectArr.length == 1) {
- if (item.year == selectStartYear && childItem.value == selectStartMonth) {
- // 开始、结束月份是否可选同一天
- if (that.isAllowSameDay == true) {
- childItem.isSelect = true;
- childItem.text = that.startEndText;
- that.monthSaveArr(item.year, childItem.value, childItem.text);
- return;
- } else {
- childItem.isSelect = true;
- childItem.text = that.startText;
- return;
- }
- }
- // 选择的月份不能超过12个月
- if ((item.year > this.selectArr[0].year && childItem.value >= this.selectArr[0].month) || (item.year - this.selectArr[0].year > 1)) {
- Toast("结束月份不能超过12个月");
- return;
- }
- if ((item.year == selectStartYear && childItem.value < selectStartMonth) || item.year < selectStartYear) {
- that.cancelSelectMonth();
- childItem.text = that.startText;
- that.monthSaveArr(item.year, childItem.value, childItem.text);
- } else {
- // 结束月份
- childItem.text = that.endText;
- that.monthSaveArr(item.year, childItem.value, childItem.text);
- that.setAreaBackground();
- }
- } else if (that.selectArr.length == 2) {
- that.cancelSelectMonth();
- childItem.text = that.startText;
- that.monthSaveArr(item.year, childItem.value, childItem.text);
- }
- childItem.isSelect = !childItem.isSelect;
- },
- // 取消已选中的月份
- cancelSelectMonth () {
- this.selectArr = [];
- this.years.map((item) => {
- item.children.map((ev) => {
- ev.text = "";
- ev.isSelect = false;
- ev.monthClass = "";
- });
- });
- },
- // 添加开始、结束区间的背景颜色
- setAreaBackground () {
- const startYear = this.selectArr[0].year; //开始年份
- const endYear = this.selectArr[1].year; //结束年份
- const startMonth = this.selectArr[0].month; //开始年份
- const endMonth = this.selectArr[1].month; //结束年份
- this.years.map((item) => {
- // 起始年份相同
- if (item.year == startYear && item.year == endYear) {
- item.children.map((ev) => {
- if (endMonth - startMonth >= 1) {
- if (ev.value == startMonth) {
- ev.monthClass = "calendarStartColor";
- } else if (ev.value == endMonth) {
- ev.monthClass = "calendarEndColor";
- } else if (ev.value > startMonth && ev.value < endMonth) {
- ev.monthClass = "calendarMiddleColor";
- }
- }
- })
- } else if (endYear > startYear) {
- // 开始年份小于结束年份
- if (item.year == startYear) {
- // 起始月份
- item.children.map((ev) => {
- if (ev.value == startMonth) {
- ev.monthClass = "calendarStartColor";
- } else if (ev.value > startMonth) {
- ev.monthClass = "calendarMiddleColor";
- }
- })
- } else if (item.year == endYear) {
- // 结束月份
- item.children.map((ev) => {
- if (ev.value == endMonth) {
- ev.monthClass = "calendarEndColor";
- } else if (ev.value < endMonth) {
- ev.monthClass = "calendarMiddleColor";
- }
- })
- } else if (item.year > startYear && item.year < endYear) {
- // 开始月份与结束月份区间的加背景色
- item.children.map((ev) => {
- ev.monthClass = "calendarMiddleColor";
- })
- }
- }
- });
- },
- // 确认
- onConfirm () {
- this.$emit("confirmMonth", this.selectArr);
- },
- // 重置日期
- onReset () {
- this.$emit("resetCalendar");
- },
- // 关闭
- closeCalendar () {
- this.$emit("closeCalendar");
- }
- }
- };
- </script>
-
- <style lang="stylus" scoped>
- /deep/.van-action-sheet__close {
- right: auto;
- left: 0px;
- }
- /deep/.van-action-sheet__header{
- font-size: 1rem;
- font-family: PingFang SC;
- font-weight: bold;
- color: #333333;
- }
- .content {
- font-family: PingFang SC;
- padding-bottom: 84px;
-
- /deep/.van-row {
- padding: 1.11rem 0 0 0;
- }
-
- /deep/.van-col--6 {
- margin-bottom: 1.11rem;
- position: relative;
- }
- .calendarStartColor{
- background-image: linear-gradient(to right, #fff , #e6f5fc);
- }
- .calendarEndColor{
- background-image: linear-gradient(to left,#fff , #e6f5fc);
- }
- .calendarMiddleColor {
- background-color: #e6f5fc;
- }
-
- .monthTitle {
- background: #E5E5E5;
- font-size: 0.83rem;
- font-weight: bold;
- color: #333333;
- padding: 0.61rem 0;
- }
-
- .monthList {
- width: 3rem;
- height: 2.22rem;
- display: flex;
- flex-flow: column;
- color: #333333;
- justify-items: center;
- align-items: center;
- border-radius: 0.56rem;
- margin: 0 auto;
- padding: 0 0.22rem 0.22rem 0.22rem;
-
- div:first-child {
- height: 0.81rem;
- line-height: 0.81rem;
- padding: 0.44rem 0 0.22rem 0;
- font-size: 0.89rem;
- font-weight: 500;
- }
-
- .startEnd {
- height: 0.61rem;
- line-height: 0.61rem;
- font-size: 0.53rem;
- font-weight: 500;
- color: #FFFEFE;
- }
-
- .fontSize {
- font-size: 0.61rem;
- }
-
- div {
- display: flex;
- flex-flow: row;
- }
- }
-
- .isDisabled {
- color: #ccc;
- }
-
- .isSelect {
- background: #0097E0;
- color: #fff;
- }
- }
-
- .footBtn {
- position: fixed;
- bottom: 0;
- width: 100%;
- padding: 0.66rem 0 1.53rem 0;
- display: flex;
- background: #fff;
-
- .footBox {
- padding: 0 16px;
- display: flex;
- flex-flow: row;
- width: 100%;
- }
-
- .van-button {
- border-radius: 2rem;
- height: 2.5rem;
- line-height: 2.5rem;
- flex: 1;
- margin: 0 1rem;
- font-size: 1rem;
- }
-
- .van-button:nth-child(1) {
- width: 80%;
- color: #000;
- font-size: 14px;
- background: white;
- border: 2px solid #666 !important;
- border-radius: 40px;
- margin: 0 1rem;
- }
-
- .van-button:nth-child(2) {
- width: 80%;
- color: #fff;
- font-size: 14px;
- background: white;
- border-radius: 40px;
- margin: 0 1rem;
- border: none;
- background: -webkit-gradient(linear, right top, left top, from(#0068b7), to(#0097e0));
- background: linear-gradient(-90deg, #0068b7, #0097e0);
- }
- }
- </style>
组件引用
- <month-filter :defaultDate="monthDate.monthDefaultDate" :calendarshow="monthDate.monthCalendarShow" :isAllowSameDay="monthDate.isAllowSameDay" :yearLength="monthDate.yearLength" @closeCalendar="monthDate.monthCalendarShow = false" @confirmMonth="selectMonth" @resetCalendar="resetMonthCalendar">
- </month-filter>
-
-
- monthDate:{
- monthCalendarShow:false,
- yearLength:10,
- monthDefaultDate:[
- new Date(), new Date() //设置区间
- ],
- isAllowSameDay:true // 可选同一个月份
- },
-
- // 选择月份区间
- selectMonth(data) {
- if(data.length ==2 ){
- // 这里是获取的开始和结束的值
- }else if(data.length==1){
- if(data[0].text !="开始/结束"){
- Toast("请选择正确的月份区间");
- return;
- }else{
- // 这里是开始和结束的月份相同
- }
- }
- this.monthDate.monthCalendarShow = false;
- },
-
- resetMonthCalendar(){ //重置月份}
-
按月区间选择组件还可优化,欢迎大家给出意见,谢谢!
效果图如下:
开始月份到结束月份
开始结束月份可选当月:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。