首页 > 其他分享 >ElementUI 季度选择器 QuarterPicker

ElementUI 季度选择器 QuarterPicker

时间:2022-10-27 16:49:58浏览次数:88  
标签:return ElementUI QuarterPicker value year date const quarter 选择器

一、在项目 components 路径下创建 quarter-picker 文件夹

  1 <!--
  2  * @Descripttion: 季度选择器
  3  * @version: 1.0
  4  * @Author: https://www.lervor.com/
  5  * @Date: 2021-12-06
  6  * @LastEditTime: 2021-12-09
  7 -->
  8 <template>
  9   <el-popover
 10     trigger="focus"
 11     v-model="pickerVisible"
 12     popper-class="lervor-quarter-popover"
 13     :disabled="disabled">
 14     <el-input
 15       ref="reference"
 16       slot="reference"
 17       class="el-date-editor"
 18       readonly
 19       :disabled="disabled"
 20       :size="size"
 21       :placeholder="placeholder"
 22       :value="displayValue"
 23       :validate-event="false"
 24       :style="{ width }"
 25       @mouseenter.native="handleMouseEnter"
 26       @mouseleave.native="showClose = false">
 27       <i slot="prefix"
 28         class="el-input__icon"
 29         :class="triggerClass">
 30       </i>
 31       <i slot="suffix"
 32         class="el-input__icon"
 33         :class="[showClose ? '' + clearIcon : '']"
 34         @click="handleClickIcon"
 35         @mousedown="handleMousedownIcon">
 36       </i>
 37     </el-input>
 38     <div class="lervor-quarter-picker">
 39       <div class="el-date-picker__header el-date-picker__header--bordered">
 40         <button
 41           type="button"
 42           aria-label="前一年"
 43           class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left"
 44           @click="prevYear">
 45         </button>
 46         <span
 47           role="button"
 48           class="el-date-picker__header-label">{{ yearLabel }}</span>
 49         <button
 50           type="button"
 51           aria-label="后一年"
 52           class="el-picker-panel__icon-btn el-date-picker__next-btn el-icon-d-arrow-right"
 53           @click="nextYear">
 54         </button>
 55       </div>
 56       <div class="el-picker-panel__content" style="width: 200px; margin: 10px 15px;">
 57         <table class="lervor-quarter-table" @click="handleTableClick">
 58           <tbody>
 59             <tr>
 60               <td class="available" :class="getCellStyle(0)">
 61                 <a class="cell">第一季度</a>
 62               </td>
 63               <td class="available" :class="getCellStyle(1)">
 64                 <a class="cell">第二季度</a>
 65               </td>
 66             </tr>
 67             <tr>
 68               <td class="available" :class="getCellStyle(2)">
 69                 <a class="cell">第三季度</a>
 70               </td>
 71               <td class="available" :class="getCellStyle(3)">
 72                 <a class="cell">第四季度</a>
 73               </td>
 74             </tr>
 75           </tbody>
 76         </table>
 77       </div>
 78     </div>
 79   </el-popover>
 80 </template>
 81 
 82 <script>
 83   import { formatDate, prevYear, nextYear, range, nextDate, isDateObject, parseDate } from 'element-ui/src/utils/date-util'
 84   import { hasClass } from 'element-ui/src/utils/dom'
 85 
 86   // 获取指定年份和季度的所有日期
 87   const datesInYearAndQuarter = (year, quarter) => {
 88     const numOfDays = getDayCountOfQuarter(year, quarter)
 89     const firstDay = new Date(year, quarter * 3, 1)
 90     return range(numOfDays).map(n => nextDate(firstDay, n))
 91   }
 92 
 93   // 获取指定年份和季度总天数
 94   const getDayCountOfQuarter = (year, quarter) => {
 95     switch(quarter) {
 96       case 0: // 第一季度包含二月,需要对是否闰年进行判断处理
 97         if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) {
 98           return 91
 99         } else {
100           return 90
101         }
102       case 1:
103         return 91
104       default:
105         return 92
106     }
107   }
108 
109   export default {
110     name: 'QuarterPicker',
111     props: {
112       size: String,
113       format: String, // 显示在输入框中的格式,引入季度:q(阿拉伯数字)、Q(中文数字)
114       valueFormat: String,
115       placeholder: String,
116       prefixIcon: String,
117       clearIcon: {
118         type: String,
119         default: 'el-icon-circle-close'
120       },
121       disabled: Boolean,
122       clearable: {
123         type: Boolean,
124         default: true
125       },
126       width: { // 组件宽度
127         type: String,
128         default: ''
129       },
130       disabledDate: {}, // 不可用的日期
131       value: null
132     },
133     data() {
134       return {
135         showClose: false,
136         pickerVisible: false,
137         date: new Date(),
138         quarterText: [ '一', '二', '三', '四' ]
139       }
140     },
141     computed: {
142       triggerClass() {
143         return this.prefixIcon || 'el-icon-date'
144       },
145       displayValue() {
146         if (!this.value) return null
147         // 季度,从0开始
148         const quarter = parseInt(this.parsedValue.getMonth() / 3)
149         let fDate = formatDate(this.parsedValue, this.format)
150         fDate = fDate.replace(/q/, quarter + 1).replace(/Q/, this.quarterText[quarter])
151         return fDate
152       },
153       year() {
154         return this.date.getFullYear()
155       },
156       yearLabel() {
157         return this.year + ' 年'
158       },
159       parsedValue() {
160         if (!this.value) {
161           return this.value
162         }
163         if (isDateObject(this.value)) {
164           return this.value
165         }
166         // 非时间格式且设置了valueFormat,进行时间转换
167         if (this.valueFormat) {
168           return parseDate(this.value, this.valueFormat)
169         }
170         // 非时间格式且未设置valueFormat,再尝试转换时间
171         return new Date(this.value)
172       }
173     },
174     watch: {
175       value(value) {
176         this.date = value ? this.parsedValue : new Date()
177       }
178     },
179     methods: {
180       handleMouseEnter() {
181         if (this.disabled) return
182         if (this.value && this.clearable) {
183           this.showClose = true
184         }
185       },
186       handleClickIcon(event) {
187         if (this.disabled) return
188         if (this.showClose) {
189           this.$emit('input', null)
190           this.$emit('change', null)
191           this.showClose = false
192           this.pickerVisible = false
193           this.$refs.reference.blur()
194         }
195       },
196       handleMousedownIcon(event) {
197         // 阻止鼠标按下清空按钮,防止清空数据时季度选择面板闪现
198         event.preventDefault()
199       },
200       handleTableClick(event) {
201         let target = event.target
202         if (target.tagName === 'A') {
203           target = target.parentNode
204         }
205         if (target.tagName !== 'TD') return
206         if (hasClass(target, 'disabled')) return
207         const column = target.cellIndex
208         const row = target.parentNode.rowIndex
209         // 季度,从0开始
210         const quarter = row * 2 + column
211         // 季度开始月份,从0开始
212         const month = quarter * 3
213         let newDate = new Date(this.year, month, 1)
214         if (this.valueFormat) {
215           newDate = formatDate(newDate, this.valueFormat)
216         }
217         this.pickerVisible = false
218         this.$emit('input', newDate)
219         this.$emit('change', newDate)
220       },
221       prevYear() {
222         this.date = prevYear(this.date)
223       },
224       nextYear() {
225         this.date = nextYear(this.date)
226       },
227       getCellStyle(quarter) {
228         const style = {}
229         const today = new Date()
230         const date = this.parsedValue ? this.parsedValue : today
231         style.disabled = typeof this.disabledDate === 'function'
232           ? datesInYearAndQuarter(this.year, quarter).every(this.disabledDate) : false
233         // 当前选中的季度样式
234         style.current = date.getFullYear() === this.year && parseInt(date.getMonth() / 3) === quarter
235         // 今日所在季度样式
236         style.quarter = today.getFullYear() === this.year && parseInt(today.getMonth() / 3) === quarter
237         return style
238       }
239     }
240   }
241 </script>
242 
243 <style>
244   .lervor-quarter-picker {
245     line-height: 30px;
246   }
247   .lervor-quarter-popover {
248     padding: 0;
249   }
250   .lervor-quarter-table {
251     font-size: 12px;
252     margin: -1px;
253     border-collapse: collapse;
254     width: 100%;
255   }
256   .lervor-quarter-table td {
257     text-align: center;
258     padding: 10px 3px;
259     cursor: pointer;
260   }
261   .lervor-quarter-table td .cell {
262     height: 32px;
263     display: block;
264     line-height: 32px;
265     color: #606266;
266     margin: 0 auto;
267   }
268   .lervor-quarter-table td .cell:hover {
269     color: #1890ff;
270   }
271 
272   .lervor-quarter-table td.current:not(.disabled) .cell {
273     color: #409eff;
274   }
275 
276   .lervor-quarter-table td.quarter .cell {
277     color: #409eff;
278     font-weight: 700;
279   }
280 
281   .lervor-quarter-table td.disabled .cell {
282     background-color: #F5F7FA;
283     cursor: not-allowed;
284     color: #C0C4CC;
285   }
286 </style>
View Code

二、创建 index.vue 文件

 1 <template>
 2   <div>
 3     <quarter-picker
 4       width="150px"
 5       format="yyyy年q季度"
 6       value-format="yyyyMM"
 7       placeholder="选择季度"
 8       v-model="quarterDate"
 9       :disabled-date="disabledQuarter"
10       @change="handleChangeQuarter" />
11   </div>
12 </template>
13 
14 <script>
15 import QuarterPicker from '@/components/quarter-picker'
16 export default {
17   components: {
18     QuarterPicker
19   },
20   data() {
21     return {
22       quarterDate: '202104',
23       // 禁用日期/季度示例,只允许选择本年度本季度(不含)之前的季度
24       disabledQuarter: time => {
25         const now = new Date()
26         return time.getFullYear() > now.getFullYear() || time.getFullYear() === now.getFullYear() && parseInt(time.getMonth() / 3) >= parseInt(now.getMonth() / 3)
27       }
28     }
29   },
30   methods: {
31     handleChangeQuarter(date) {
32       console.info(date)
33     }
34   }
35 }
36 </script>
View Code

最终效果:

 

 

代码参考:https://www.lervor.com/archives/244/

标签:return,ElementUI,QuarterPicker,value,year,date,const,quarter,选择器
From: https://www.cnblogs.com/zyn123/p/16832750.html

相关文章

  • elementui手动触发大图预览
    实现效果不需要点击el-image组件,而且通过其他方式自由触发大图预览效果写法原本想通过获取el-imagedom元素,dom.click()来进行触发。发现不生效。查了一下,如下方法可以......
  • CSS选择器
    一.、选择器进阶 1.复合选择器1.1后代选择器:空格   1.2子代选择器:>   2. 并集选择器利用 ”,“隔开   3.交集选择器紧挨着  ......
  • CSS基础选择器和扩展选择器
    CSS-选择器-基础选择器分类:基础选择器:1.基础选择器1.id选择器:选择器具体的id属性值的元素,建议在一个html页面中id值唯一......
  • vue+elementUI-Table,实现自定义表格列效果
    都是日常的工作小结,编写不易,转载请注明出处~考虑到会看我博客的都是和我一样的小白,尽量写细一些,有问题可在评论区留言一实现原理1.1一般我们在写elementUI表格代码时,都......
  • elementui table type="expand" 实现点击行展开行
    <el-tablefitbordersize="small":data="deviceList"ref="dataTreeList"@expand-change="handleExpandChange"><el-table-columntype="expand">//如果表......
  • Kubernetes--Pod节点选择器nodeSelector(标签)
    Pod节点选择器是标签及标签选择器的一种应用,它能够让Pod对象基于集群中工作节点的标签来挑选倾向运行的目标节点。Kubernetes的kube-scheduler守护进程负责在各工作节点......
  • CSS-选择器-扩展选择器和CSS-属性1
    CSS-选择器-扩展选择器扩展选择器:1.选择所有元素:语法:*{}2.并集选择器:选择器1,选择器2{}3.子选择器:筛选选择器1元素下的选择器2元素语法:选择器1选......
  • CSS-语法格式和CSS-选择器-基础选择器
    CSS-语法格式CSS语法:格式:选择器{属性名1:属性值1;属性名2:属性值2...}选择器:筛选具有相似特征的元素注意:......
  • k8s基础篇 pod(六)节点选择器
    6.node节点选择器我们在创建pod资源的时候,pod会根据schduler进行调度,那么默认会调度到随机的一个工作节点,如果我们想要pod调度到指定节点或者调度到一些具有相同特点的node......
  • Kubernetes--标签选择器(标签)
    标签选择器用于表达标签的查询条件或选择标准,KubernetesAPI目前支持两个选择器:基于等值关系(equality-based)以及基于集合关系(set-based)。例如,env=production和env!=qa......