vue?+?element-ui?季度選擇器組件?el-quarter-picker示例詳解
使用說(shuō)明
1、復(fù)制組件文件 ElQuarterPicker.vue 到項(xiàng)目(依賴(lài)element-ui),組件源碼在后面
2、引用并調(diào)用組件
<template> <div class="app-container"> <el-quarter-picker v-model="value" placeholder="選擇季度" /> </div> </template> <script> import ElQuarterPicker from './ElQuarterPicker' export default { components: { ElQuarterPicker }, data() { return { value: '' } } } </script>
ElQuarterPicker.vue
<template> <div class="el-quarter-picker"> <el-popover v-model="visible" :disabled="!canPopover" :tabindex="null" placement="bottom-start" transition="el-zoom-in-top" trigger="click"> <div class="el-date-picker"> <div class="el-picker-panel__body"> <div class="el-date-picker__header el-date-picker__header--bordered" style="margin:0px; line-height:30px"> <button type="button" @click="clickLast" aria-label="前一年" class="el-picker-panel__icon-btn el-date-picker__prev-btn el-icon-d-arrow-left"></button> <span role="button" class="el-date-picker__header-label" @click="clickYear">{{ title }}</span> <button type="button" @click="clickNext" aria-label="后一年" class="el-picker-panel__icon-btn el-date-picker__next-btn el-icon-d-arrow-right"></button> </div> <div class="el-picker-panel__content" style="margin:0px; width:100%"> <table class="el-month-table" style=""> <tbody> <tr v-for="line in lineCount" :key="line"> <td v-for="index in (line * 4 <= viewList.length ? 4 : viewList.length - (line - 1) * 4)" :key="index" :class="{ today: viewList[(line - 1) * 4 + index - 1].current, current: viewList[(line - 1) * 4 + index - 1].active }"> <div><a class="cell" @click="clickItem(viewList[(line - 1) * 4 + index - 1])">{{ viewList[(line - 1) * 4 + index - 1].label }}</a></div> </td> </tr> </tbody> </table> </div> </div> </div> <el-input slot="reference" @change="changeText" @mouseenter.native="mouseEnter" @mouseleave.native="mouseLeave" :placeholder="placeholder" v-model="text" :size="size" :readonly="!canEdit" :disabled="disabled"> <i slot="prefix" class="el-input__icon el-icon-date"></i> <i slot="suffix" class="el-input__icon el-icon-circle-close" v-show="showClear" style="cursor:pointer" @click.stop="clear"></i> </el-input> </el-popover> </div> </template> <script> export default { name: 'ElQuarterPicker', props: { placeholder: { type: String, default: '' }, size: { type: String, default: '' }, readonly: { type: Boolean, default: false }, clearable: { type: Boolean, default: true }, editable: { type: Boolean, default: true }, disabled: { type: Boolean, default: false }, format: { type: String, default: 'yyyy年第Q季度' }, valueFormat: { type: String, default: 'yyyy-qq' }, value: { type: String, default: '' } }, model: { prop: 'value', event: 'change' }, watch: { value(val) { // console.log('change-------', val) this.changeValue(val) }, readonly(val) { this.canEdit = !val && this.editable this.canPopover = !this.disabled && !val }, editable(val) { this.canEdit = !this.readonly && val }, disabled(val) { this.canPopover = !val && !this.readonly } }, data() { return { visible: false, showClear: false, // 控制清空按鈕展示 canEdit: true, // 是否可編輯 canPopover: true, // 選擇器彈出是否可用 text: '', // 文本框值 viewType: 1, // 視圖類(lèi)型,1季度,2年度 viewYear: 0, // 當(dāng)前年份 viewList: [], // 數(shù)據(jù)列表 lineCount: 0, // 數(shù)據(jù)行數(shù) title: '', // 選擇器標(biāo)題 data: [0, 0] // 當(dāng)前選擇年度-季度 } }, mounted() { // console.log('mounted--------', this.value) this.changeValue(this.value) // 設(shè)置文本框是否可編輯 this.canEdit = !this.readonly && this.editable this.canPopover = !this.disabled && !this.readonly // 監(jiān)聽(tīng)按鍵(上下左右鍵可以切換季度) document.onkeydown = (event) => { if (this.visible) { const data = [this.data[0], this.data[1]] if (data[0] < 1 || data[1] < 1) { // 以當(dāng)前季度為標(biāo)準(zhǔn) const curDate = new Date() data[0] = curDate.getFullYear() data[1] = parseInt(curDate.getMonth() / 3) + 1 } if (event.code === 'ArrowLeft') { // 上一個(gè)季度 if (data[1] === 1) { data[0] = data[0] - 1 data[1] = 4 } else { data[1] = data[1] - 1 } } else if (event.code === 'ArrowRight') { // 下一個(gè)季度 if (data[1] === 4) { data[0] = data[0] + 1 data[1] = 1 } else { data[1] = data[1] + 1 } } else if (event.code === 'ArrowUp') { // 上一年季度 data[0] = data[0] - 1 } else if (event.code === 'ArrowDown') { // 下一年季度 data[0] = data[0] + 1 } else { return } // 超過(guò)年限的不處理 if (data[0] < 1000 || data[0] > 9999) { return } this.data = data this.viewType = 1 this.viewYear = data[0] this.$emit('change', this.formatTo(data, this.valueFormat)) } } }, destroyed() { document.onkeydown = null }, methods: { // 季度文本變更 changeText() { if (this.checkFormat(this.format, this.text)) { // 設(shè)置值 this.formatFrom(this.text, this.format) this.$emit('change', this.formatTo(this.data, this.valueFormat)) } else { // 輸入了無(wú)效的格式,還原回原來(lái)的值 if (this.data[0] < 1 || this.data[1] < 1) { this.text = '' } else { this.text = this.formatTo(this.data, this.format) } } this.visible = false }, // 鼠標(biāo)進(jìn)入 mouseEnter() { if (!this.disabled && !this.readonly && this.clearable && this.text !== '') { this.showClear = true } }, // 鼠標(biāo)離開(kāi) mouseLeave() { if (!this.disabled && this.clearable) { this.showClear = false } }, // 清除季度 clear() { this.showClear = false this.visible = false this.$emit('change', '') }, // 季度值變更 changeValue(val) { this.viewType = 1 if (val) { // 反向格式化 this.formatFrom(val, this.valueFormat) this.text = this.formatTo(this.data, this.format) this.viewYear = this.data[0] } else { this.text = '' this.data = [0, 0] this.viewYear = new Date().getFullYear() } this.initView() }, // 初始化視圖數(shù)據(jù) initView() { const list = [] const curDate = new Date() const curYear = curDate.getFullYear() const curQuarter = parseInt(curDate.getMonth() / 3) + 1 if (this.viewType === 1) { let index = 0 for (const i of '一二三四') { index++ const item = { label: '第' + i + '季度', year: this.viewYear, quarter: index, current: false, active: false } if (this.viewYear === curYear && index === curQuarter) { item.current = true } else if (this.viewYear === this.data[0] && index === this.data[1]) { item.active = true } list.push(item) } this.title = this.viewYear + ' 年' } else { const start = parseInt(this.viewYear / 10) * 10 this.viewYear = start for (let i = 0; i < 10; i++) { const year = start + i const item = { label: year + '', year: year, current: false, active: false } if (year === curYear) { item.current = true } else if (year === this.data[0]) { item.active = true } list.push(item) } this.title = start + ' 年 - ' + (start + 9) + ' 年' } this.viewList = list this.lineCount = parseInt(list.length / 4) if (list.length % 4 > 0) { this.lineCount++ } }, // 校驗(yàn)季度格式是否正確 checkFormat(pattern, val) { // 格式轉(zhuǎn)成正則表達(dá)式 let text = '' for (const char of pattern) { const dict = '\\^$.+?*[]{}!' if (dict.indexOf(char) === -1) { text += char } else { text += '\\' + char } } text = text.replace('yyyy', '[1-9]\\d{3}') text = text.replace('qq', '0[1-4]') text = text.replace('q', '[1-4]') text = text.replace('Q', '[一二三四]') text = '^' + text + '$' const patt = new RegExp(text) return patt.test(val) }, // 格式化季度到指定格式 formatTo(data, pattern) { let text = pattern.replace('yyyy', '' + data[0]) text = text.replace('qq', '0' + data[1]) text = text.replace('q', '' + data[1]) text = text.replace('Q', '一二三四'.substr(data[1] - 1, 1)) return text }, // 以指定格式解析季度 formatFrom(str, pattern) { const year = this.findText(str, pattern, 'yyyy') const quarter = this.findText(str, pattern, ['qq', 'q', 'Q']) this.data = [year, quarter] }, // 查找文本數(shù)值 findText(str, pattern, find) { if (find instanceof Array) { for (const f of find) { const val = this.findText(str, pattern, f) if (val !== -1) { return val } } return -1 } const index = pattern.indexOf(find) if (index === -1) { return index } const val = str.substr(index, find.length) if (find === 'Q') { return '一二三四'.indexOf(val) + 1 } else { return parseInt(val) } }, // 年份點(diǎn)擊 clickYear() { if (this.viewType !== 1) { return } // 切換年度選擇器 this.viewType = 2 this.initView() }, // 季度選擇 clickItem(item) { // console.log('select--------', item) if (this.viewType === 1) { // 選擇季度 this.$emit('change', this.formatTo([item.year, item.quarter], this.valueFormat)) this.visible = false } else { // 選擇年度 this.viewType = 1 this.viewYear = item.year this.initView() } }, // 上一年 clickLast() { if (this.viewYear > 1000) { if (this.viewType === 1) { this.viewYear-- this.initView() } else { this.viewYear = this.viewYear - 10 this.initView() } } }, // 下一年 clickNext() { if (this.viewYear < 9999) { if (this.viewType === 1) { this.viewYear++ this.initView() } else { this.viewYear = this.viewYear + 10 this.initView() } } } } } </script> <style> .el-quarter-picker { width: 220px; display: inline-block; } </style>
參考文檔
到此這篇關(guān)于vue + element-ui 季度選擇器組件 el-quarter-picker的文章就介紹到這了,更多相關(guān) element-ui 季度選擇器組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- element-ui時(shí)間日期選擇器限制選擇范圍的幾種場(chǎng)景
- vue項(xiàng)目element-ui級(jí)聯(lián)選擇器el-cascader回顯的問(wèn)題及解決
- element-ui動(dòng)態(tài)級(jí)聯(lián)選擇器回顯問(wèn)題詳解(二十多行代碼搞定)
- 解決element-ui的el-select選擇器的@blur事件失效的坑
- 詳解element-ui日期時(shí)間選擇器的日期格式化問(wèn)題
- element-ui 時(shí)間選擇器限制范圍的實(shí)現(xiàn)(隨動(dòng))
- vue2.0 element-ui中el-select選擇器無(wú)法顯示選中的內(nèi)容(解決方法)
相關(guān)文章
詳解使用jest對(duì)vue項(xiàng)目進(jìn)行單元測(cè)試
這篇文章主要介紹了詳解使用jest對(duì)vue項(xiàng)目進(jìn)行單元測(cè)試,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue實(shí)現(xiàn)在進(jìn)行增刪改操作后刷新頁(yè)面
這篇文章主要介紹了vue實(shí)現(xiàn)在進(jìn)行增刪改操作后刷新頁(yè)面,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08vue中使用heatmapjs的示例代碼(結(jié)合百度地圖)
這篇文章主要介紹了vue中使用heatmapjs的示例代碼(結(jié)合百度地圖),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09關(guān)于Vue中img動(dòng)態(tài)拼接src圖片地址的問(wèn)題
這篇文章主要介紹了關(guān)于Vue中img動(dòng)態(tài)拼接src圖片地址的問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10解決vuejs 使用value in list 循環(huán)遍歷數(shù)組出現(xiàn)警告的問(wèn)題
今天小編就為大家分享一篇解決vuejs 使用value in list 循環(huán)遍歷數(shù)組出現(xiàn)警告的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09完美解決vue 項(xiàng)目開(kāi)發(fā)越久 node_modules包越大的問(wèn)題
這篇文章主要介紹了vue 項(xiàng)目開(kāi)發(fā)越久 node_modules包越大的問(wèn)題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09