目錄
#核心程式碼實作
1、梳理想法
2、初始化所需的資料
3 、初始化日曆的各項屬性
4、根據日曆屬性產生日曆日期的數據
5、新增範本和樣式部分
#結語
首頁 web前端 Vue.js 詳解怎麼使用vue封裝一個自訂日曆組件

詳解怎麼使用vue封裝一個自訂日曆組件

Apr 02, 2023 am 07:30 AM
前端 vue.js 數據視覺化

怎麼開發一個自訂日曆的vue元件,以下這篇文章就手把手教你如何封裝一個自訂行事曆元件,希望對大家有幫助!

詳解怎麼使用vue封裝一個自訂日曆組件

眾所周知啊,一般來說,如果專案中有需要用到行事曆元件,往往是找第三方UI函式庫中的元件來使用,或是找現成的其他第三方插件。對很多朋友來說,第一眼看到日曆組件,下意識的就會覺得很複雜,無從下手。但是當我閱讀了這個日曆插件的源碼之後,發現並沒有我想像中的複雜。我以前傻傻得認為,想要做一個日曆組件,得需要把距離現在年份前後至少十年的日曆資料都獲取到,然後才能進行下一步的開發。

然而,在我嘗試著閱讀了dycalendar.js這個函式庫的源碼之後,一方面感覺自己太笨了,把問題想得太複雜了。另外也感慨作者思路之清晰。看完後感覺受益匪淺。

在將作者的思路邏輯梳理完畢後,我依據這個思路開發了一個vue元件。如下圖所示:

詳解怎麼使用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的值為:

詳解怎麼使用vue封裝一個自訂日曆組件

4、根據日曆屬性產生日曆日期的數據

當我們已經知道本月第一天對應的周幾索引值本月一共有多少天上個月一共有多少天這三個核心資料之後,就可以開始產生對應的日曆資料了。

想法如下

  1. 由於大部分情況下,本月的第一天不是從頭開始的,之前的部分是上個月的日期。所以第一行要單獨處理。
  2. 設定一個公用的date數值,初始值設定為1。然後從本月第一天對應的周幾索引值開始進行遞增。本月之前的日期和之後的日期設定一個演算法進行計算。
  3. 為了方便之後進行日期切換、樣式區分,將產生的資料加工成一個對象,其中包含日期類型-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/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/024/f9b43de5b51dc0478df08b202300d1c6-2.png" 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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

PHP與Vue:完美搭檔的前端開發利器 PHP與Vue:完美搭檔的前端開發利器 Mar 16, 2024 pm 12:09 PM

PHP與Vue:完美搭檔的前端開發利器在當今網路快速發展的時代,前端開發變得愈發重要。隨著使用者對網站和應用的體驗要求越來越高,前端開發人員需要使用更有效率和靈活的工具來創建響應式和互動式的介面。 PHP和Vue.js作為前端開發領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結合,以及詳細的程式碼範例,幫助讀者更好地理解和應用這兩

Graphviz 教學:打造直覺資料視覺化 Graphviz 教學:打造直覺資料視覺化 Apr 07, 2024 pm 10:00 PM

Graphviz是一款開源工具包,可用於繪製圖表和圖形,它使用DOT語言指定圖表結構。安裝Graphviz後,可以使用DOT語言建立圖表,例如繪製知識圖譜。產生圖形後,可以使用Graphviz強大的功能來視覺化您的數據並提高其可理解性。

Django是前端還是後端?一探究竟! Django是前端還是後端?一探究竟! Jan 19, 2024 am 08:37 AM

Django是一個由Python編寫的web應用框架,它強調快速開發和乾淨方法。儘管Django是web框架,但要回答Django是前端還是後端這個問題,需要深入理解前後端的概念。前端是指使用者直接和互動的介面,後端是指伺服器端的程序,他們透過HTTP協定進行資料的互動。在前端和後端分離的情況下,前後端程式可以獨立開發,分別實現業務邏輯和互動效果,資料的交

前端面試官常問的問題 前端面試官常問的問題 Mar 19, 2024 pm 02:24 PM

在前端開發面試中,常見問題涵蓋廣泛,包括HTML/CSS基礎、JavaScript基礎、框架和函式庫、專案經驗、演算法和資料結構、效能最佳化、跨域請求、前端工程化、設計模式以及新技術和趨勢。面試官的問題旨在評估候選人的技術技能、專案經驗以及對行業趨勢的理解。因此,應試者應充分準備這些方面,以展現自己的能力和專業知識。

Go語言前端技術探秘:前端開發新視野 Go語言前端技術探秘:前端開發新視野 Mar 28, 2024 pm 01:06 PM

Go語言作為一種快速、高效的程式語言,在後端開發領域廣受歡迎。然而,很少有人將Go語言與前端開發聯繫起來。事實上,使用Go語言進行前端開發不僅可以提高效率,還能為開發者帶來全新的視野。本文將探討使用Go語言進行前端開發的可能性,並提供具體的程式碼範例,幫助讀者更了解這一領域。在傳統的前端開發中,通常會使用JavaScript、HTML和CSS來建立使用者介面

PHP 資料結構的視覺化技術 PHP 資料結構的視覺化技術 May 07, 2024 pm 06:06 PM

PHP資料結構視覺化有三種主要技術:Graphviz:開源工具,可建立圖表、有向無環圖和決策樹等圖形表示。 D3.js:JavaScript函式庫,用於建立互動式、資料驅動的視覺化,從PHP產生HTML和數據,再用D3.js在客戶端視覺化。 ASCIIFlow:用於建立文字表示資料流程圖的函式庫,適合流程和演算法的視覺化。

Django:前端和後端開發都能搞定的神奇框架! Django:前端和後端開發都能搞定的神奇框架! Jan 19, 2024 am 08:52 AM

Django:前端和後端開發都能搞定的神奇框架! Django是一個高效、可擴展的網路應用程式框架。它能夠支援多種Web開發模式,包括MVC和MTV,可以輕鬆地開發出高品質的Web應用程式。 Django不僅支援後端開發,還能夠快速建構出前端的介面,透過模板語言,實現靈活的視圖展示。 Django把前端開發和後端開發融合成了一種無縫的整合,讓開發人員不必專門學習

Golang與前端技術結合:探討Golang如何在前端領域發揮作用 Golang與前端技術結合:探討Golang如何在前端領域發揮作用 Mar 19, 2024 pm 06:15 PM

Golang與前端技術結合:探討Golang如何在前端領域發揮作用,需要具體程式碼範例隨著互聯網和行動應用的快速發展,前端技術也愈發重要。而在這個領域中,Golang作為一門強大的後端程式語言,也可以發揮重要作用。本文將探討Golang如何與前端技術結合,以及透過具體的程式碼範例來展示其在前端領域的潛力。 Golang在前端領域的角色作為一門高效、簡潔且易於學習的

See all articles