您好,登錄后才能下訂單哦!
這篇文章主要介紹“vue3怎么開發detePicker日期選擇組件”,在日常操作中,相信很多人在vue3怎么開發detePicker日期選擇組件問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”vue3怎么開發detePicker日期選擇組件”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
vue3 + tailwindcss + ts
html結構
<template> <div> <-- 這里放input框 --> <div></div> <-- 點擊input彈出日歷 --> <div> <-- 頭部 --> <div></div> <-- 星期 --> <div></div> <-- 日歷主體 --> <div></div> <-- 按鈕組 --> <div></div> </div> </div> </template>
input框,
代碼如下:
<div class="block w-full h-[32px] relative border rounded-md"> <input class="placeholder:text-[#B2B2B2] block w-full h-full rounded-md py-2 pl-2 pr-9 text-sm focus:outline-none focus:ring-0" disabled placeholder="選擇時間" type="text" maxlength="32" /> <div class="absolute inset-y-0 right-0 flex items-center pr-2 cursor-pointer" > <svg class="w-4 h-4 fill-[#C2C2C2]"> <use xlink:href="#icon-riqi" rel="external nofollow" /> </svg> </div> </div>
頭部,
代碼如下
<div class="flex justify-center"> <svg class="w-4 h-4 fill-[#C2C2C2] rotate-90 cursor-pointer"> <use xlink:href="#icon-down" rel="external nofollow" rel="external nofollow" /> </svg> <span class="text-xs mx-5">二月2023</span> <svg class="w-4 h-4 fill-[#C2C2C2] rotate-[270deg] cursor-pointer"> <use xlink:href="#icon-down" rel="external nofollow" rel="external nofollow" /> </svg> </div>
星期,
代碼如下:
<div class="grid grid-cols-7 auto-cols-[20px] auto-rows-[20px] text-xs mt-2 mx-[9px] justify-items-center gap-x-2.5" > <span>一</span> <span>二</span> <span>三</span> <span>四</span> <span>五</span> <span>六</span> <span>日</span> </div>
日歷主體,
代碼如下:
<div class="grid grid-cols-7 auto-cols-[20px] auto-rows-[20px] text-xs mt-2 mx-[9px] gap-y-2 gap-x-2.5" > <span :class="[ 'cursor-pointer w-full h-full flex justify-center items-center', v.color, { '!bg-[#60C2CC] rounded-full !text-white': actives.one === v.time || actives.two === v.time, }, setBgColor(v.time), ]" v-for="(v, i) in days" :key="i" >{{ v.day }}</span > </div>
這里主要是用了,v-bind動態屬性,來顯示不同狀態下的日歷格子的樣式(比如選中某天)
按鈕組,
代碼如下:
<div class="flex justify-between items-center mt-2.5 mx-[9px]"> <span class="text-xs text-[#9C9C9C]">跳到今天</span> <div class="w-[50px] h-5 bg-[#60C2CC] rounded-lg text-white leading-5 text-center text-xs" > 確定 </div> </div>
整體樣式如下:
顯示切換邏輯,主要是點擊input,彈出日歷
// 控制顯示的變量 const isShow = ref(false) // 點擊按鈕的時候顯示 const openTimeSelect = () => { isShow.value = true } // 點擊確定,或者點擊日歷主體外的任何窗體的時候關閉,關閉的時候清空選中 const closeTimeSelect = () => { isShow.value = false actives.one = '' actives.two = '' }
定義變量,主要是定義日歷用到的數據,和接口
// 本組件唯一定義的類型 interface DaysType { day: number color: string time: string } const date = new Date() // 時間 const year = ref(0) // 年 const month = ref(0) // 月 const days = ref<DaysType[]>([]) // 需要循環渲染的日歷主體數據 // 選中某天的數據,可以選中兩天 const actives = reactive({ one: '', two: '', }) // 計算屬性,把當前點擊選中的日期轉換成時間戳 const oneTimeNum = computed(() => new Date(actives.one).getTime()) const twoTimeNum = computed(() => new Date(actives.two).getTime())
為什么說,使用ts寫的代碼,但是只定義了一個接口,在vue3 + ts的開發中,我推薦的是使用類型推導的方式去寫代碼,有時候,你會發現,你寫的ts類型多此一舉。當然,你是ts藝術體操選手,那另說。
獲取日歷主體渲染的數據,邏輯如下: 具體代碼如下:
const updateTime = () => { days.value = [] year.value = date.getFullYear() // 獲取當前年 month.value = date.getMonth() + 1 // 獲取當前月份 const curDays = new Date(year.value, month.value, 0).getDate() // 當前月的天數 let curWeek = new Date(year.value, month.value - 1, 1).getDay() // 這個月第一天星期幾 curWeek <= 0 ? (curWeek = 7) : curWeek // 如果值是0的話,那么本月第一天是周日 const preDays = new Date(year.value, month.value - 1, 0).getDate() // 上個月的天數 const preLastDay = curWeek - 1 // 獲取上一個月有多少天 // 插入上一個月的日期 for (let i = 0; i < preLastDay; i++) { days.value.unshift({ day: preDays - i, color: 'text-[#CECECE]', time: `${year.value}-${month.value - 1}-${preDays - i}`, }) } // 插入本月的日期 for (let i = 1; i <= curDays; i++) { days.value.push({ day: i, color: 'text-[#191919]', time: `${year.value}-${month.value}-${i}`, }) } const lastPreDays = 42 - curDays - preLastDay // 插入下個月的日期 for (let i = 1; i <= lastPreDays; i++) { days.value.push({ day: i, color: 'text-[#CECECE]', time: `${year.value}-${month.value + 1}-${i}`, }) } }
日歷主體分為三個部分,1、前一個月的天數,2、當前月的天數,3、下一個月的天數
通過date 內置對象,獲取到:當前年,當前月,當前月有幾天,當前月的第一天是星期幾,上個月有多少天
通過 當前月第一天是星期幾 減去 1 得到,上個月一共有幾天要顯示
獲取上個月的天數 循環 上個月一共有幾天,得到上個月具體的日期,比如說:
上個月有2天要顯示,上個月一共有31天,那么本月第一天往前兩個格子是上月的。
2次循環
第一次,31 - 0 得到31
第二次,31 - 1 得到30
如下圖所示:
獲取本月的天數 通過循環當前月的天數獲取
獲取下月的天數 一共42個格子,那么42 減去當前月天數,減去上個月天數,就是下個月要顯示多少天,同樣循環獲取
上一月和下一月
// 上一月 const prevMonth = () => { date.setMonth(date.getMonth() - 1) updateTime() } // 下一月 const nextMonth = () => { date.setMonth(date.getMonth() + 1) updateTime() }
主要是通過 dete 對象的 setMonth 方法重置月份,月份重置后,調用獲日歷主體方法就可獲取到上一個月和下一個月的日歷主體
選擇兩個日期選中,邏輯如下:
const selectTime = (item: DaysType) => { const timeNum = new Date(item.time).getTime() if (!actives.one || timeNum < oneTimeNum.value) { actives.one = item.time } if (!actives.two || timeNum > oneTimeNum.value) { actives.two = item.time } }
首先在html中綁定點擊事件,點擊獲取的時候把當前選中的對象傳遞下來
對象中有個字段是 2023-2-28 這樣的格式,這個格式,可以通過 date 對象的 getTime 方法轉換成時間戳
如果第一次選中沒有值,或者 當前選中的值小于 第一次選中的日期,那么存入第一次選中
如果第二次選中沒有紙,或者 當前選中的值大于 第一次選中的日期,那么存入第二次選中
請注意:這里存入的時候,會自動通過計算屬性把值轉換為時間戳
給兩個點之間添加背景色,邏輯如下:
const setBgColor = (time: string) => { const timeNum = new Date(time).getTime() if ( oneTimeNum.value && twoTimeNum.value && oneTimeNum.value <= timeNum && timeNum <= twoTimeNum.value ) { return 'bg-[#DFF3F5]' } }
還是通過轉換時間戳的方式,去做對比
處于兩個選中日期中間的 格子 會返回個背景色
然后通過動態class的方式插入顏色就可以了
到此,關于“vue3怎么開發detePicker日期選擇組件”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。