ant框架年份组件
看了ant框架针对于年份不能自定义插槽内容所以放弃用ant框架年份组件,自定义插槽内容是想实现年份下方可以加小圆点的需求,因加小圆点需求必须实现,决定自己封装组件来实现需求,自己实现的效果呢类似于ant年份控件 在这里做一下记录。
效果图如下:
1.YearPicker.vue
<template><div class="year-picker" ><q-inputoutlinedv-model="contentValue"dense@blur="blurEvent"@focus="inputFocus"placeholder="选择年份"clearable@clear="clearHandle"class="col"></q-input><transition name="fade"><div class="year-picker__year-box" v-if="showYearContent"><div class="year-picker__year-title"><span class="to-left" @click="toLeft()"><DoubleLeftOutlined style="rgba(0, 0, 0, 0.45)"/></span><span class="to-middle">{{yearStart}}-{{yearEnd-1}}</span><span class="to-right" @click="toRight()"><DoubleRightOutlined style="rgba(0, 0, 0, 0.45)"/></span></div><div class="year-picker__year-content" ><span v-for="(item,index) in yearList" :key="index" style="position: relative;"><div class="listItem" :class="{listItemBgC: item === checkedIndex,'year-disable':yearDis(item)}" @click="chooseYear(item,index)">{{item}}</div><div :class="getAllYear(item)" ></div></span></div></div></transition></div>
</template>
<script>
import { ref, shallowRef, watch, nextTick, onMounted, inject,reactive ,computed,toRefs,getCurrentInstance,watchEffect} from 'vue'
import {DoubleLeftOutlined,DoubleRightOutlined} from '@ant-design/icons-vue'
export default {name: 'index',components:{DoubleLeftOutlined,DoubleRightOutlined},props: {yearDisable: {type: String,default: 'no'},contentValue: {type: Number,},allDataList:{type: Array,default: ()=>{return []}},},setup(props,context) {const { yearDisable } = toRefs(props);const checkedIndex = ref()const state = reactive({yearLists: [],showYearContent: false,yearStart: 2010,yearEnd: 2030,blurIndex:null,allDataList:[],})const contentValue = ref()watch(() => props.contentValue, (newvalue) => {if(newvalue){contentValue.value = newvaluecontext.emit('handlerInput',newvalue)}}, {immediate: true})watch(() => props.allDataList, (value) => {if(!value) returnstate.allDataList = value}, {immediate: true})const inputFocus = ()=> {state.showYearContent = true}const blurEvent= (e)=> {state.showYearContent = false}const chooseYear=(year,index)=> {if (year > yearDis.value) returnstate.showYearContent = falsecheckedIndex.value = yearcontext.emit('handlerInput', year)}const toLeft=()=> {state.yearStart -= 20state.yearEnd -= 20state.showYearContent = true}const toRight=()=> {state.yearStart += 20state.yearEnd += 20state.showYearContent = true}const yearDis = computed(()=>{return function (y) {switch (yearDisable.value) {case 'before': {return y < new Date().getFullYear()}break;case 'no': {return false}break;case 'after': {return y > new Date().getFullYear()}}}})const yearList = computed(()=>{let arr = []for (let i = state.yearStart; i < state.yearEnd; i++) {arr.push(i)}return arr})const clearHandle = (value)=>{checkedIndex.value = ''}//实现年份下方加小圆点事件const getAllYear = (year) => {if(state.allDataList.findIndex(mon => mon === year) !== -1){return 'checkbox1'}else{return 'defultbox1'}}return {...toRefs(state),yearDis,getAllYear,yearList,checkedIndex,clearHandle,inputFocus,contentValue,blurEvent,chooseYear,toLeft,toRight,}},
}
</script><style scoped lang="scss">
.checkbox1{position: absolute;left: 50%;height: 5px;width: 8px;border-radius: 5px;background-color: #ff9800;transform: translate3d(-50%,0,0)
}
.defultbox1{position: absolute;left: 50%;height: 5px;width: 8px;border-radius: 5px;
}
.year-picker {::v-deep(.q-field--dense .q-field__control){height: 32px!important;}::v-deep(.q-field--dense .q-field__marginal){height: 32px!important;}.col{box-sizing: border-box;margin: 0;color: rgba(0, 0, 0, 0.88);font-size: 14px;height: 32px!important;position: relative;display: inline-flex;align-items: center;background: #ffffff;border-radius: 6px;transition: border 0.2s,box-shadow;}.col:hover{border: none!important;margin: 0;}margin-left: 20px;display: inline-block;border-radius: 5px;.year-picker__icon {position: absolute;transform: translate(-26px, 10px);color: #d9d9d9}.year-picker__input--real:hover {border: 1px solid rgba(0, 122, 244, 0.8);}.year-picker__year-title {height: 40px;width: 270px;border-top: 1px solid #d4d4d4;border-bottom: 1px solid #d4d4d4;display: flex;justify-content: space-around;align-items: center;.to-middle{font-weight: bold;color: #666666;}span {color: #525252;cursor: pointer;}span:active {opacity: .5;}}.year-picker__year-box {position: absolute;z-index: 10;background: #ffffff;border-radius: 5px;border: 1px solid #eeeeee;box-shadow: 0 0 .38rem 0 rgba(0, 0, 0, 0.1);transform: translateY(-32px);left:36px;top:72px;}.year-picker__year-content {padding-top: 20px;width: 270px;height: 250px;display: flex;flex-wrap: wrap;justify-content: space-around;.listItem{color: #525252;font-size: 14px;width: 48px;height: 25px;display: flex;justify-content: center;align-items: center;margin-bottom: 2px;}.listItem:hover{cursor: pointer;}.listItemBgC{background-color: #0067c0;color:white;border-radius: 3px;}.year-disable {background: #f5f5f5;}.year-disable:hover {cursor: no-drop;background: #f5f5f5;}}
}
.fade-enter,
.fade-leave-to {opacity: 0;transform: translateY(-30px);
}
/* 过程 */
.fade-enter-active {transition: all 0.5s;
}
/* 结束 */
.fade-enter-to {opacity: 1;
}
.fade-leave-active {transition: all 0.5s;
}.dark {border: 1px solid blue;color: #8099b3;.year-picker__input {background: #003366;color: #8099b3;;}.year-picker__input--real {border: 1px solid blue;height: 32px;}.year-picker__input::placeholder {color: #1c5389;}.year-picker__year-title {border-top: 1px solid blue;border-bottom: 1px solid blue;span {color: #8099b3;}}.year-text:hover {cursor: pointer;background: rgba(157, 219, 252, 0.41);border-radius: 3px;}.year-picker__year-content {.year-text {color: #8099b3;}.year-disable {background: #133558;}.year-disable:hover {cursor: no-drop;background: #133558;}}
}
</style>
vue 使用组件
<YearPicker :contentValue="contentValue" @handlerInput="handlerInput" :year-disable="'no'" :allDataList="allDataList"/>
const state = reactive({contentValue:'', //选中的年份allDataList:[2018,2019],// 加这个属性呢是实现年份下方加黄色小圆点})//组件里选中的年份传过来的事件const handlerInput = (value) =>{console.log(value)state.contentValue = value}