怎麼開發一個自訂日曆的vue元件,以下這篇文章就手把手教你如何封裝一個自訂行事曆元件,希望對大家有幫助!
眾所周知啊,一般來說,如果專案中有需要用到行事曆元件,往往是找第三方UI函式庫中的元件來使用,或是找現成的其他第三方插件。對很多朋友來說,第一眼看到日曆組件,下意識的就會覺得很複雜,無從下手。但是當我閱讀了這個日曆插件的源碼之後,發現並沒有我想像中的複雜。我以前傻傻得認為,想要做一個日曆組件,得需要把距離現在年份前後至少十年的日曆資料都獲取到,然後才能進行下一步的開發。
然而,在我嘗試著閱讀了dycalendar.js這個函式庫的源碼之後,一方面感覺自己太笨了,把問題想得太複雜了。另外也感慨作者思路之清晰。看完後感覺受益匪淺。
在將作者的思路邏輯梳理完畢後,我依據這個思路開發了一個vue元件。如下圖所示:
接下來,就隨著我一起看看如何開發自己的行事曆元件。 【相關推薦:vuejs影片教學、web前端開發】
#核心程式碼實作
1、梳理想法
- 取得到目標日期資料
- 取得到目前日期的各項重要屬性,諸如
目前年
,目前月
,目前日期
,當前星期幾
,當前月一共有幾天
,當前月的第一天對應的是星期幾
,上個月總共有多少天
等。 - 根據這些屬性,來產生特定的
日曆日期資料清單
,然後將其循環渲染到範本中。 - 當切換月份的時候,取得到新的目標日期對應的各項關鍵資料。 vue偵測到日曆屬性變更之後,通知頁面進行更新。
2、初始化所需的資料
一般來說,成熟的行事曆元件,日期都是一個雙向綁定的變數。為了方便使用,我們也採用雙向綁定的方式。
<script>import { reactive, ref, computed, watch } from "vue";const props = defineProps({ modelValue: Date, });const emits = defineEmits(["update:modelValue"]);/** * 最小年份 */const MIN_YEAR = 1900;/** * 最大年份 */const MAX_YEAR = 9999;/** * 目标日期 */const targetDate = ref(props.modelValue);复制代码</script>
接下來,我們還需要初始化一些常數用來表示月份和日期:
/** * 有关月度的名称列表 */const monthNameList = { chineseFullName: [ "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月", ], fullName: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ], mmm: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ], };/** * 有关周几的名称列表 */const dayNameList = [ { chineseFullName: "周日", chineseShortName: "日", fullName: "Sunday", shortName: "Sun", dayNumber: 0, }, { chineseFullName: "周一", chineseShortName: "一", fullName: "Monday", shortName: "Mon", dayNumber: 1, }, { chineseFullName: "周二", chineseShortName: "二", fullName: "Tuesday", shortName: "Tue", dayNumber: 2, }, { chineseFullName: "周三", chineseShortName: "三", fullName: "Wednesday", shortName: "Wed", dayNumber: 3, }, { chineseFullName: "周四", chineseShortName: "四", fullName: "Thursday", shortName: "Thu", dayNumber: 4, }, { chineseFullName: "周五", chineseShortName: "五", fullName: "Friday", shortName: "Fri", dayNumber: 5, }, { chineseFullName: "周六", chineseShortName: "六", fullName: "Saturday", shortName: "Sat", dayNumber: 6, }, ];复制代码
接下來,準備幾個vue的回應式資料:
/** * 今日 */const today = new Date();/** * 日历的各项属性 */const calendarProps = reactive({ target: { year: null, month: null, date: null, day: null, monthShortName: null, monthFullName: null, monthChineseFullName: null, firstDay: null, firstDayIndex: null, totalDays: null, }, previous: { totalDays: null, }, });/** * 用于展现的日历数据 */const calendarData = ref([]);复制代码
3 、初始化日曆的各項屬性
接下來,透過setCalendarProps
方法取得行事曆的各個屬性,逐一填入calendarProps
中的資料:
function setCalendarProps() { if (!targetDate.value) { targetDate.value = today; } // 获取目标日期的年月日星期几数据 calendarProps.target.year = targetDate.value.getFullYear(); calendarProps.target.month = targetDate.value.getMonth(); calendarProps.target.date = targetDate.value.getDate(); calendarProps.target.day = targetDate.value.getDay(); if ( calendarProps.target.year MAX_YEAR ) { console.error("无效的年份,请检查传入的数据是否是正常"); return; } // 获取到目标日期的月份【中文】名称 let dateString; dateString = targetDate.value.toString().split(" "); calendarProps.target.monthShortName = dateString[1]; calendarProps.target.monthFullName = monthNameList.fullName[calendarProps.target.month]; calendarProps.target.monthChineseFullName = monthNameList.chineseFullName[calendarProps.target.month]; // 获取目标月份的第一天是星期几,和在星期几中的索引值 const targetMonthFirstDay = new Date( calendarProps.target.year, calendarProps.target.month, 1 ); calendarProps.target.firstDay = targetMonthFirstDay.getDay(); calendarProps.target.firstDayIndex = dayNameList.findIndex( (day) => day.dayNumber === calendarProps.target.firstDay ); // 获取目标月份总共多少天 const targetMonthLastDay = new Date( calendarProps.target.year, calendarProps.target.month + 1, 0 ); calendarProps.target.totalDays = targetMonthLastDay.getDate(); // 获取目标月份的上个月总共多少天 const previousMonth = new Date( calendarProps.target.year, calendarProps.target.month, 0 ); calendarProps.previous.totalDays = previousMonth.getDate(); }复制代码
要注意的一個知識點是,在取得本月多少天和上個月多少天的時候,都將date值設定為了
0
。這是因為當date值為0
的時候,傳回的Date物件是上個月的最後一天。所以說,為了取得本月多少天,需要將本月的month值加1
。
執行這個方法之後,此時calendarProps
的值為:
4、根據日曆屬性產生日曆日期的數據
當我們已經知道本月第一天對應的周幾索引值、本月一共有多少天和上個月一共有多少天這三個核心資料之後,就可以開始產生對應的日曆資料了。
想法如下:
- 由於大部分情況下,本月的第一天不是從頭開始的,之前的部分是上個月的日期。所以第一行要單獨處理。
- 設定一個公用的date數值,初始值設定為
1
。然後從本月第一天對應的周幾索引值開始進行遞增。本月之前的日期和之後的日期設定一個演算法進行計算。 - 為了方便之後進行日期切換、樣式區分,將產生的資料加工成一個對象,其中包含日期類型-
dateType
,表示是本月還是上月還是下個月;
/** * 生成日历的数据 */function setCalendarData() { let i; let date = 1; const originData = []; const firstRow = []; // 设置第一行数据 for (i = 0; i <p>至此,這個日曆元件的核心部分的邏輯就已經實現了。你看,是不是很簡單呢? </p><p>接下來,我們只需要根據<code>calendarData</code>中的資料渲染出對應的html模板和新增上樣式就可以了。 </p><h3 id="新增範本和樣式部分">5、新增範本和樣式部分</h3><p>#一般來說,日曆元件都是網格狀的結構,所以我選擇table的方式來渲染。不過你要問我還有沒有別的方式,那還是有的,例如使用flex佈局或grid佈局,但是如果採用這種方式的話,<code>calendarData</code>的資料結構就不是現在這個樣子了。 </p><p>dom結構如下圖:</p><p><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/024/f9b43de5b51dc0478df08b202300d1c6-2.png?x-oss-process=image/resize,p_40" class="lazy" alt="詳解怎麼使用vue封裝一個自訂日曆組件" loading="lazy"></p><p>至於按鈕邊框的流動效果,是我參考蘇甦的文章做的,詳情請見:</p> <blockquote><p>Clip-path實現按鈕流動邊框動畫<a href="https://www.php.cn/link/eb04e52cfac45c0399533bfd050d8c22" target="_blank" title="https://www.php.cn/link/eb04e52cfac45c0399533bfd050d8c22">juejin.cn/post/719877…</a></p></blockquote><p>然後剩下的樣式部分,即興發揮或根據UI設計圖繪製即可。 <span style="max-width:90%">想必各位都領教過UI姐姐們精美的設計圖吧(嘻嘻</span></p><p>具體的代碼部分就不貼在文章中了,如有需要可以直接查看下方的完整源碼</p><blockquote><p><a href="https://www.php.cn/link/501949e07f27c5dd9ca3b8dc62913aa1" target="_blank" title="https://gitee.com/wushengyuan/diy-calendard/" ref="nofollow noopener noreferrer">gitee.com/wushengyuan…</a></p></blockquote><h2 id="結語">#結語</h2><p>有些感覺很麻煩的元件,可能核心邏輯往往不是那麼複雜。有些時候,可能只是需要一些耐心,將程式碼一行一行的拆解出來閱讀,理清楚其中的思路。</p><p>(學習影片分享:<a href="https://www.php.cn/course/list/18.html" target="_blank">vuejs入門教學</a>、<a href="https://www.php.cn/course/list/91.html" target="_blank" textvalue="编程基础视频">程式設計基礎影片</a>)</p>
以上是詳解怎麼使用vue封裝一個自訂日曆組件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Vue.js與前端技術棧緊密集成,提升開發效率和用戶體驗。 1)構建工具:與Webpack、Rollup集成,實現模塊化開發。 2)狀態管理:與Vuex集成,管理複雜應用狀態。 3)路由:與VueRouter集成,實現單頁面應用路由。 4)CSS預處理器:支持Sass、Less,提升樣式開發效率。

Netflix選擇React來構建其用戶界面,因為React的組件化設計和虛擬DOM機制能夠高效處理複雜界面和頻繁更新。 1)組件化設計讓Netflix將界面分解成可管理的小組件,提高了開發效率和代碼可維護性。 2)虛擬DOM機制通過最小化DOM操作,確保了Netflix用戶界面的流暢性和高性能。

Vue.js被開發者喜愛因為它易於上手且功能強大。 1)其響應式數據綁定係統自動更新視圖。 2)組件系統提高了代碼的可重用性和可維護性。 3)計算屬性和偵聽器增強了代碼的可讀性和性能。 4)使用VueDevtools和檢查控制台錯誤是常見的調試技巧。 5)性能優化包括使用key屬性、計算屬性和keep-alive組件。 6)最佳實踐包括清晰的組件命名、使用單文件組件和合理使用生命週期鉤子。

Vue.js是一個漸進式的JavaScript框架,適用於構建高效、可維護的前端應用。其關鍵特性包括:1.響應式數據綁定,2.組件化開發,3.虛擬DOM。通過這些特性,Vue.js簡化了開發過程,提高了應用性能和可維護性,使其在現代Web開發中備受歡迎。

Vue.js和React各有優劣,選擇取決於項目需求和團隊情況。 1)Vue.js適合小型項目和初學者,因其簡潔和易上手;2)React適用於大型項目和復雜UI,因其豐富的生態系統和組件化設計。

Vue.js通過多種功能提升用戶體驗:1.響應式系統實現數據即時反饋;2.組件化開發提高代碼復用性;3.VueRouter提供平滑導航;4.動態數據綁定和過渡動畫增強交互效果;5.錯誤處理機制確保用戶反饋;6.性能優化和最佳實踐提升應用性能。

Vue.js在Web開發中的角色是作為一個漸進式JavaScript框架,簡化開發過程並提高效率。 1)它通過響應式數據綁定和組件化開發,使開發者能專注於業務邏輯。 2)Vue.js的工作原理依賴於響應式系統和虛擬DOM,優化性能。 3)實際項目中,使用Vuex管理全局狀態和優化數據響應性是常見實踐。

Vue.js是由尤雨溪在2014年發布的漸進式JavaScript框架,用於構建用戶界面。它的核心優勢包括:1.響應式數據綁定,數據變化自動更新視圖;2.組件化開發,UI可拆分為獨立、可複用的組件。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)