亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么封裝一個vue自定義日歷組件

發布時間:2023-04-13 10:08:13 來源:億速云 閱讀:138 作者:iii 欄目:編程語言

這篇文章主要介紹“怎么封裝一個vue自定義日歷組件”,在日常操作中,相信很多人在怎么封裝一個vue自定義日歷組件問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么封裝一個vue自定義日歷組件”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

核心代碼實現

1、梳理思路

  • 獲取到目標日期數據

  • 獲取到當前日期的各項重要屬性,諸如當前年當前月當前日期當前星期幾當前月一共有幾天當前月的第一天對應的是星期幾上個月總共有多少天等。

  • 根據這些屬性,來生成具體的日歷日期數據列表,然后將其循環渲染到模板中。

  • 當切換月份的時候,獲取到新的目標日期對應的各項關鍵數據。vue檢測到日歷屬性變化之后,通知頁面進行更新。

2、初始化所需要的數據

一般來說,成熟的日歷組件,日期都是一個雙向綁定的變量。為了方便使用,我們也采用雙向綁定的方式。

<script setup>
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);

接下來,我們還需要初始化一些常量用來表示月份和日期:

/**
* 有關月度的名稱列表
*/
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 < MIN_YEAR ||
   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 <= 6; i++) {
   // 設置目標月份之前月份的日期數據
   if (i < calendarProps.target.firstDayIndex) {
     const previousDate =
       calendarProps.previous.totalDays -
       calendarProps.target.firstDayIndex +
       (i + 1);
     firstRow.push({
       dateObj: new Date(
         calendarProps.target.year,
         calendarProps.target.month - 1,
         previousDate
       ),
       dateNumber: previousDate,
       dateType: "previous"
     });
   } else {
     // 設置目標月份當月的日期數據
     firstRow.push({
       dateObj: new Date(
         calendarProps.target.year,
         calendarProps.target.month,
         date
       ),
       dateNumber: date,
       dateType: "current"
     });
     date++;
   }
 }
 originData.push(firstRow);
 // 設置后面五行的數據
 for (let j = 0; j <= 4; j++) {
   const rowData = [];
   for (let k = 0; k <= 6; k++) {
     // 設置目標月份剩下的日期數據
     if (date <= calendarProps.target.totalDays) {
       rowData.push({
         dateObj: new Date(
           calendarProps.target.year,
           calendarProps.target.month,
           date
         ),
         dateNumber: date,
         dateType: "current"
       });
     } else {
       // 設置目標月份下個月的日期數據
       const nextDate = date - calendarProps.target.totalDays;
       rowData.push({
         dateObj: new Date(
           calendarProps.target.year,
           calendarProps.target.month + 1,
           nextDate
         ),
         dateNumber: nextDate,
         dateType: "next"
       });
     }
     date++;
   }
   originData.push(rowData);
 }
 calendarData.value = originData;
}

至此,這個日歷組件的核心部分的邏輯就已經實現了。你看,是不是很簡單?

接下來,我們只需要根據calendarData中的數據渲染出相應的html模板和添加上樣式就可以了。

5、添加模板和樣式部分

一般來說,日歷組件都是網格狀的結構,所以我選擇table的方式進行渲染。不過你要是問我還有沒有別的方式,那還是有的,比如使用flex布局或者grid布局,但是如果采用這種方式的話,calendarData的數據結構就不是現在這個樣子了。

dom結構如下圖:

怎么封裝一個vue自定義日歷組件

到此,關于“怎么封裝一個vue自定義日歷組件”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

神木县| 吴江市| 浠水县| 瑞丽市| 甘肃省| 鹤山市| 罗源县| 平阳县| 平陆县| 渭南市| 石屏县| 铁岭县| 百色市| 依安县| 波密县| 鄱阳县| 南充市| 永平县| 淅川县| 汝州市| 仁化县| 新化县| 潼南县| 广西| 东港市| 海林市| 奉节县| 儋州市| 达州市| 宁海县| 天津市| 甘泉县| 台山市| 阿拉善右旗| 临夏县| 腾冲县| 德兴市| 皮山县| 当阳市| 马公市| 东阳市|