91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

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

如何使用vue封裝一個自定義日歷組件

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

本文小編為大家詳細介紹“如何使用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

梁山县| 克拉玛依市| 美姑县| 武强县| 青州市| 兴义市| 财经| 乌拉特中旗| 莱芜市| 安顺市| 桓仁| 青河县| 黄石市| 镇平县| 海安县| 淮北市| 顺昌县| 芒康县| 塔河县| 科尔| 子洲县| 杭州市| 太白县| 双桥区| 平陆县| 三台县| 乐业县| 偏关县| 濉溪县| 平南县| 拜城县| 繁昌县| 远安县| 安阳市| 武威市| 耿马| 伊金霍洛旗| 湘潭县| 大埔县| 陕西省| 大方县|