Heim >Web-Frontend >View.js >Ausführliche Erklärung, wie man mit Vue eine benutzerdefinierte Kalenderkomponente kapselt

Ausführliche Erklärung, wie man mit Vue eine benutzerdefinierte Kalenderkomponente kapselt

青灯夜游
青灯夜游nach vorne
2023-04-02 07:30:022103Durchsuche

So entwickeln Sie eine benutzerdefinierte Kalender-Vue-Komponente. Im folgenden Artikel erfahren Sie Schritt für Schritt, wie Sie eine benutzerdefinierte Kalenderkomponente kapseln.

Ausführliche Erklärung, wie man mit Vue eine benutzerdefinierte Kalenderkomponente kapselt

Wie wir alle wissen, wird die Kalenderkomponente bei Bedarf in einem Projekt im Allgemeinen häufig von Komponenten in UI-Bibliotheken von Drittanbietern oder anderen vorgefertigten Plug-Ins von Drittanbietern verwendet. ins. Wenn viele Freunde die Kalenderkomponente zum ersten Mal sehen, denken sie unbewusst, dass sie sehr kompliziert ist und keinen Einstieg finden. Aber als ich den Quellcode dieses Kalender-Plug-Ins las, stellte ich fest, dass es nicht so kompliziert war, wie ich dachte. Früher dachte ich törichterweise, wenn ich eine Kalenderkomponente erstellen wollte, müsste ich Kalenderdaten für mindestens zehn Jahre vor und nach dem aktuellen Jahr erhalten, bevor ich mit dem nächsten Entwicklungsschritt fortfahren konnte.

Nachdem ich jedoch versucht hatte, den Quellcode von dycalendar.js zu lesen, hatte ich einerseits das Gefühl, dass ich zu dumm war und das Problem für zu kompliziert hielt. Ich bewundere auch die klare Denkweise des Autors. Nachdem ich es gelesen hatte, hatte ich das Gefühl, dass es mir sehr geholfen hat.

Nachdem ich die Ideenlogik des Autors geklärt hatte, entwickelte ich eine Vue-Komponente basierend auf dieser Idee. Wie im Bild unten gezeigt:

Ausführliche Erklärung, wie man mit Vue eine benutzerdefinierte Kalenderkomponente kapselt

Folgen Sie mir als Nächstes, um zu sehen, wie Sie Ihre eigene Kalenderkomponente entwickeln. [Verwandte Empfehlungen: vuejs-Video-Tutorial, Web-Front-End-Entwicklung]

Kerncode-Implementierung

1. Sortieren Sie die Ideen

  • Erhalten Sie die Zieldatumsdaten
  • Erhalten Sie die wichtigen Attribute des aktuellen Datums, wie zum Beispiel Aktuelles Jahr, Aktueller Monat, Aktuelles Datum, Aktueller Wochentag, Wie viele Tage im aktuellen Monat Code>, Der erste Tag des aktuellen Monats entspricht dem Wochentag, Wie viele Tage gab es im letzten Monat , usw. 当前年当前月当前日期当前星期几当前月一共有几天当前月的第一天对应的是星期几上个月总共有多少天等。
  • 根据这些属性,来生成具体的日历日期数据列表,然后将其循环渲染到模板中。
  • 当切换月份的时候,获取到新的目标日期对应的各项关键数据。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的值为:

Ausführliche Erklärung, wie man mit Vue eine benutzerdefinierte Kalenderkomponente kapselt

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></p> Generieren Sie basierend auf diesen Attributen eine bestimmte <code>Kalenderdatumsdatenliste</code> und rendern Sie sie dann in einer Schleife in die Vorlage. 🎜🎜Besorgen Sie sich beim Monatswechsel die Eckdaten zum neuen Zieldatum. Nachdem Vue Änderungen in Kalenderattributen erkennt, wird die Benachrichtigungsseite aktualisiert. 🎜<h3 data-id="heading-3">2. Für die Initialisierung erforderliche Daten🎜🎜Im Allgemeinen ist das Datum in ausgereiften Kalenderkomponenten eine bidirektional gebundene Variable. Aus Gründen der Benutzerfreundlichkeit verwenden wir auch eine Zwei-Wege-Bindung. 🎜rrreee🎜Als nächstes müssen wir auch einige Konstanten initialisieren, um den Monat und das Datum darzustellen: 🎜rrreee🎜Als nächstes bereiten wir einige Vue-Reaktionsdaten vor: 🎜rrreee<h3 data-id="heading-4">3 Initialisieren Sie die verschiedenen Attribute des Kalenders🎜🎜Als nächstes erhalten Sie die verschiedenen Attribute des Kalenders über die Methode <code>setCalendarProps</code> und geben die Daten nacheinander in <code>calendarProps</code> ein: 🎜rrreee<blockquote>🎜 Zu beachtende Dinge Ein Wissenspunkt ist, dass bei der Ermittlung der Anzahl der Tage in diesem Monat und der Anzahl der Tage im letzten Monat der Datumswert auf <code>0</code> gesetzt wird. Dies liegt daran, dass das zurückgegebene Datumsobjekt der letzte Tag des vorherigen Monats ist, wenn der Datumswert <code>0</code> ist. Um die Anzahl der Tage in diesem Monat zu erhalten, müssen Sie daher <code>1</code> zum Monatswert dieses Monats hinzufügen. 🎜</blockquote>🎜Nach der Ausführung dieser Methode ist der Wert von <code>calendarProps</code>: 🎜🎜<img src="https://img.php.cn/upload/article/000/000/%20024%20/814bdf07f8933c02a732ffbb6ee244e1-1.png" alt="Ausführliche Erklärung, wie man mit Vue eine benutzerdefinierte Kalenderkomponente kapselt" loading="lazy">🎜<h3 data-id="heading-5">4. Generieren Sie Kalenderdatumsdaten basierend auf Kalenderattributen🎜🎜Wenn wir wissen der <strong>Indexwert des Wochentags, der dem ersten Tag dieses Monats entspricht</strong>, <strong>die Gesamtzahl der Tage in diesem Monat</strong> und <strong>die Gesamtzahl der Tage in den letzten Monat</strong> Nach dem Sammeln der Kerndaten können Sie mit der Generierung der entsprechenden Kalenderdaten beginnen. 🎜🎜<strong>Die Idee ist wie folgt</strong>: 🎜<ol>🎜Da der erste Tag des Monats in den meisten Fällen nicht von vorne beginnt, ist der vorherige Teil das Datum des Vormonats. Daher muss die erste Zeile separat verarbeitet werden. 🎜🎜Legen Sie einen öffentlichen Datumswert fest und der Anfangswert wird auf <code>1</code> gesetzt. Beginnen Sie dann mit der Erhöhung ab dem Indexwert für den Wochentag, der dem <strong>ersten Tag des Monats</strong> entspricht. Legen Sie einen Algorithmus fest, um Daten vor und nach diesem Monat zu berechnen. 🎜🎜Um den Datumswechsel und die Stilunterscheidung später zu erleichtern, werden die generierten Daten in einem Objekt verarbeitet, das den Datumstyp <code>dateType</code> enthält und angibt, ob es sich um diesen Monat, den vorherigen Monat oder den nächsten handelt Monat; 🎜 ol>rrreee🎜An diesem Punkt wurde die Kernlogik dieser Kalenderkomponente implementiert. Sehen Sie, ist das nicht ganz einfach? 🎜🎜Als nächstes müssen wir nur noch die entsprechende HTML-Vorlage rendern und Stile basierend auf den Daten in <code>calendarData</code> hinzufügen. 🎜<h3 data-id="heading-6">5. Fügen Sie den Vorlagen- und Stilteil hinzu</h3>
<p> Im Allgemeinen haben Kalenderkomponenten eine gitterartige Struktur, daher wähle ich die Tabellenmethode zum Rendern. Wenn Sie mich jedoch fragen, ob es andere Möglichkeiten gibt, gibt es immer noch einige, z. B. die Verwendung eines Flex-Layouts oder eines Raster-Layouts. Wenn diese Methode jedoch verwendet wird, ist die Datenstruktur von <code>calendarData</code> nicht mehr so, wie sie jetzt ist. </p>
<p>Die Dom-Struktur ist wie folgt: </p>
<p><img src="https://img.php.cn/upload/article/000/000/024/f9b43de5b51dc0478df08b202300d1c6-2.png" alt="Ausführliche Erklärung, wie man mit Vue eine benutzerdefinierte Kalenderkomponente kapselt" loading="lazy"></p>
<p>Was den fließenden Effekt des Knopfrandes betrifft, habe ich ihn unter Bezugnahme auf den Artikel von Su Su erstellt, siehe: </p>
<blockquote><p>Clip-Pfad realisiert den Knopffluss Randanimation<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>Dann kann der verbleibende Stilteil improvisiert oder gemäß der UI-Designzeichnung gezeichnet werden. <span style="text-decoration:line-through;">Ich glaube, Sie alle haben die exquisiten Designzeichnungen der UI-Schwestern erlebt (hee hee</span></p>
<p>Der spezifische Codeteil wird nicht im Artikel veröffentlicht. Bei Bedarf können Sie den vollständigen Quellcode unten direkt anzeigen</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 data-id="heading-7">Fazit</h2>
<p>Bei einigen Komponenten, die sich problematisch anfühlen, ist die Kernlogik möglicherweise nicht so kompliziert. Manchmal braucht man einfach etwas Geduld, um den Code Zeile für Zeile zu lesen und die Ideen zu klären </p>
<p> ( Lernvideo-Sharing: <a href="https://www.php.cn/course/list/18.html" target="_blank">Vuejs-Einführungs-Tutorial</a>, <a href="https://www.php.cn/course/list/91.html" target="_blank" textvalue="编程基础视频">Grundlegendes Programmiervideo</a>)</p>
</ol>
</h3>
</h3>
</h3>

Das obige ist der detaillierte Inhalt vonAusführliche Erklärung, wie man mit Vue eine benutzerdefinierte Kalenderkomponente kapselt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen