When writing this component. element el-date-picker has no type=”months” feature to select multiple months. Now if you want to select multiple months, you can use element directly. This article is just for the record.
1. Use el-date-picker type=”months” directly
<div class="container"> <div class="block"> <span class="demonstration">week</span> <el-date-picker v-model="value1" type="week" format="yyyy week WW" placeholder="select week"> </el-date-picker> </div> <div class="block"> <span class="demonstration">month</span> <el-date-picker v-model="value2" type="month" placeholder="select month"> </el-date-picker> </div> </div> <div class="container"> <div class="block"> <span class="demonstration">year</span> <el-date-picker v-model="value3" type="year" placeholder="select year"> </el-date-picker> </div> <div class="block"> <span class="demonstration">Multiple dates</span> <el-date-picker type="dates" v-model="value4" placeholder="Select one or more dates"> </el-date-picker> </div> </div> <div class="container"> <div class="block"> <span class="demonstration">multiple months</span> <el-date-picker type="months" v-model="value5" placeholder="Select one or more months"> </el-date-picker> </div> <div class="block"> <span class="demonstration">multiple years</span> <el-date-picker type="years" v-model="value6" placeholder="Select one or more years"> </el-date-picker> </div> </div> <script> export default { data() { return { value1: '', value2: '', value3: '', value4: '', value5: '', value6: '' }; } }; </script>
2. Package components yourself
1. Create a new component SelectMonths.vue
<template> <div id="boxArea" ref="selectMonths" class="selectMonthBoxSquare rel clearFixed"> <el-popover v-model="visible" placement="bottom" width="250" trigger="click" > <el-input slot="reference" v-model="inputValue" class="inputStyle" type="text" size="small" :placeholder="placeholder" readonly @focus="showBox = true"> <i slot="prefix" class="el-input__icon el-icon-date"></i> <i v-if="showClear" slot="suffix" class="el-input__icon el-icon-circle-close clearIconStyle" @click="resetMonth"></i> </el-input> <div class="selectContentBox"> <div class="contentArea"> <div class="flex flex-wrap flex-around" style="padding: 15px 0;border-bottom: 1px solid #e5e5e5;"> <div v-if="curIndex == DateList.length - 1" class="cursor el-icon-d-arrow-left" style="width: 15%; color: gray;" /> <div v-else class="cursor el-icon-d-arrow-left" style="width: 15%;" @click="reduceYear" /> <div>{<!-- -->{ OneY }}Year</div> <div v-if="curIndex == 0" class="cursor t-r el-icon-d-arrow-right" style="width: 15%; color: gray;" /> <div v-else class="cursor t-r el-icon-d-arrow-right" style="width: 15%;" @click="addYear" /> </div> <div class="conterList"> <el-checkbox-group v-model="optTime[curIndex].queryTime" class="flex flex-wrap" @change="onChange"> <el-row class="monthRow"> <el-col v-for="(item,index) in DateList[curIndex].queryTime" :key="index" :span="6" class="monthCol"> <el-checkbox :class="[{'today': item === currentM & amp; & amp; curIndex === (DateList.length - 1) / 2}, 'onSelect flex-x-center']" :label="`${DateList[curIndex].TimeYear}-${(item<=9)?`0${item}`:item}`"> {<!-- -->{ monthMap[item] }} month </el-checkbox> </el-col> </el-row> </el-checkbox-group> </div> </div> <div class="buttonBox t-r"> <el-button class="buttonStyle" size="mini" plain @click.stop="resetMonth">Reset</el-button> <el-button class="buttonStyle" size="mini" type="primary" plain @click.stop="handleSubmit">OK</el-button> </div> </div> </el-popover> </div> </template> <script> export default { name: 'SelectMonths', props: { placeholder: { type: String, default: 'Please select the query month' } }, data() { return { DateList: [], // year and month array optTime: [], // Array of selected results for the month OneY: '', // current year currentM: '', // current month curIndex: 0, // current year subscript value optTimes: [], // all selected results when clicking the month resultTimes: [], // The selection result after clicking the "OK" button showBox: false, // Whether to display the month selection box visible: false, inputValue: '', // the binding value of the input box showClear: false, // Whether to display the "clear" small icon on the right side of the input box monthMap: { // The month is displayed in Chinese '1 a', '2': 'two', '3': 'three', '4': 'four', '5': 'five', '6': 'six', '7': 'seven', '8': 'eight', '9': 'nine', '10': 'ten', '11': 'Eleventh', '12': 'twelve' } } }, created() { this.init() }, mounted() { // Click anywhere outside the popup box to close the popup window in the area document. addEventListener('click', (e) => { // Get popup window object const boxArea = document. getElementById('boxArea') // Determine whether the click object is included in the popup window object if (boxArea & amp; & amp; !boxArea. contains(e. target)) { // Determine whether the currently selected month is consistent with the selection result when the "OK" button was clicked last time const equalArr = this.resultTimes.sort().toString() === this.optTimes.sort().toString() if (!equalArr) { // If inconsistent (because it is multiple selection, the query must be performed after clicking the "OK" button): // Restore the selection result to the result when the "OK" button was clicked last time this.optTimes = this.resultTimes // Restore the value of the input box to the value when the "OK" button was clicked last time this.inputValue = this.optTimes.join(',') // Determine whether to render the empty icon according to whether the input box has a value this.showClear = !!this.inputValue !== '' // Restore the selected month to the selected month when the "OK" button was clicked last time const _opt = this.resultTimes.map(v => { return v.substring(0, 4) }) for (const item in this. optTime) { this.optTime[item].queryTime = [] _opt. map((items, indexes) => { if (items === this. optTime[item]. TimeYear) { this.optTime[item].queryTime.push(this.resultTimes[indexes]) } }) } } // close popup this. showBox = false } }) }, methods: { // Initialize the data, get the first 20 years, and then loop. There are 12 months in each year to get the array opTime and DateList init() { const _this = this const_opt = [] const _optTime = [] const arr = new Array(12) const optDate = this. getDateList() optDate. map((item, index) => { // The value bound to el-checkbox-group when selecting the month _optTime[index] = { TimeYear: item. value, queryTime: [] } // Set 12 months for each year, used when el-checkbox initializes the display _opt[index] = { TimeYear: item. value, queryTime: [] } for (let i = 1; i <= arr. length; i ++ ) { _opt[index].queryTime.push(i) } }) _this.optTime = _optTime _this. DateList = _opt _this.curIndex = (_this.DateList.length - 1) / 2 // console. log('_this. curIndex', _this. curIndex) }, // Get the list of years in the past 20 years, sorted in reverse order, with the latest year at the top getDateList() { const Dates = new Date() const year = Dates. getFullYear() this.OneY = year this.currentM = Dates.getMonth() + 1 const startyear = Dates.getFullYear() - 20 const endyear = Dates.getFullYear() + 20 const Years = [] for (let i = startyear; i <= endyear; i ++ ) { const currentYear = { key: i, value: i } Years. push(currentYear) } return Years. reverse() }, // Sure handleSubmit() { const _this = this // Update the value of the input box _this.inputValue = _this.optTimes.join(',') // Determine whether to render the empty icon according to whether the input box has a value _this.showClear = !!_this.inputValue !== '' // Save the selection result of clicking the "OK" button (where this value will be used: when clicking on an area outside the pop-up frame to close the pop-up frame, in mounted) _this.resultTimes = _this.optTimes // close popup _this. showBox = false _this.visible = false _this.$emit('submitBtn', _this.resultTimes) }, // reset resetMonth() { const _this = this // reset the year to the current year const Dates = new Date() const year = Dates. getFullYear() _this.OneY = year _this.curIndex = (_this.DateList.length - 1) / 2 // Clear the selected month _this.optTimes = [] for (const i in _this. optTime) { _this.optTime[i].queryTime = [] } // Clear the input box _this.inputValue = '' // Judging whether to render the empty icon according to whether the input box has a value, it must not be rendered here this. showClear = false // Clear the selection result of clicking the "OK" button _this.resultTimes = [] // Close the month selection popup _this. showBox = false _this.visible = false _this.$emit('resetBtn', _this.resultTimes) }, // Decrease the year in the upper left corner reduceYear() { const _this = this // If it is already the last year, the year cannot be decreased any more if (_this. curIndex === _this. DateList. length - 1) return // The current subscript value + 1, get the year value according to the subscript value _this.curIndex = _this.curIndex + 1 _this.OneY = _this.DateList[_this.curIndex].TimeYear }, // Increase the year in the upper left corner addYear() { const _this = this // If it is already the current year, the year cannot be increased if (_this. curIndex === 0) return // The current subscript value -1, get the year value according to the subscript value _this.curIndex = _this.curIndex - 1 _this.OneY = _this.DateList[_this.curIndex].TimeYear }, // select month onChange() { const _this = this // Traverse the selected months in optTime, and stuff the selected results into the optTimes array const _opt = _this. optTime const arr = [] for (const item in _opt) { if (_opt[item].queryTime.length > 0) _opt[item].queryTime.filter(v => { arr.push(v) }) } _this.optTimes = arr // Update the value of the input box _this.inputValue = _this.optTimes.join(',') // Determine whether to render the empty icon according to whether the input box has a value _this.showClear = !!_this.inputValue !== '' } } } </script> <style lang="scss" scoped> .flex { display: -webkit-box; display: -webkit-flex; display: flex; justify-content: center; } .flex-wrap { flex-wrap: wrap; } .flex-around { justify-content: space-around; } .flex-x-center { display: -webkit-box; display: -webkit-flex; display: flex; -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; } .selectMonthBoxSquare { // width: 250px; width: 100%; .selectContentBox { position: absolute; top: 35px; left: 0; z-index: 2021; background: #ffffff; border: 1px solid #e5e5e5; border-radius: 3px; .contentArea { width: 330px; } } } .inputStyle { width: 100%; } .clearIconStyle { display: none; } .inputStyle:hover .clearIconStyle{ display: block; } .conterList{ .monthCol{ .today { color: #1890ff; } } .onSelect{ // width: 25% !important; padding: 3px 0; margin: 20px 0 !important; } } ::v-deep.el-checkbox__input { display: none !important; } ::v-deep.el-checkbox__label { padding-left: 0px !important; } ::v-deep .el-checkbox__input.is-checked + .el-checkbox__label { color: #fff; } label.el-checkbox.onSelect.flex-x-center.is-checked { background: #409EFF; width: 50px; border-radius: 15px; } .lableStyle { font-size: 14px; } .el-button --mini { padding: 5px 15px; font-size: 12px; border-radius: 3px; } .buttonBox { border-top: 1px solid #e5e5e5; padding: 10px; display: flex; justify-content: flex-end; } </style>
2. Use the component SelectMonths
<template> <div class="app-container"> <div> <span class="label">Month:</span> <Select Months ref="selectMonths" v-model="monthsValue" placeholder="Please select a month" @submitBtn="submitBtn" @resetBtn="resetBtn" /> </div> </div> </template> <script> import SelectMonths from '@/components/SelectMonths' export default { components: { Select Months }, data() { return { monthsValue: null } }, methods: { submitBtn(val) { const months = JSON. parse(JSON. stringify(val)) const monthsArr = months. map(item => { return item.concat('-01') }) this.monthsValue = monthsArr.join(',') }, resetBtn() { this. monthsValue = null }, } } </script>