Hagamos un calendario mensual con tecnología Vue

 

 

 


Índice
  1. Paso 1: comenzar con el marcado básico
  2. Paso 2: componentes del encabezado
  3. Paso 3: componentes de la cuadrícula del calendario
  4. Paso 4: configurar el calendario del mes actual

¿Alguna vez ha visto un calendario en una página web y ha pensado: cómo diablos hicieron eso? Para algo así, podría ser natural recurrir a un complemento, o incluso a un Google Calendar integrado, pero en realidad es mucho más sencillo crear uno de lo que piensas. Especialmente cuando utilizamos el poder impulsado por componentes de Vue.

 

He configurado una demostración en CodeSandbox para que puedas ver lo que pretendemos, pero siempre es una buena idea explicar lo que intentamos hacer:

  • Cree una cuadrícula de vista mensual que muestre los días del mes actual
  • Muestra las fechas del mes anterior y siguiente para que la cuadrícula esté siempre llena
  • Indica la fecha actual
  • Mostrar el nombre del mes seleccionado actualmente
  • Navegar al mes anterior y siguiente
  • Permitir al usuario regresar al mes actual con un solo clic

Ah, y crearemos esto como una aplicación de una sola página que recupera las fechas del calendario de Day.js, una biblioteca de utilidades súper liviana.

Paso 1: comenzar con el marcado básico

Saltaremos directamente a las plantillas. Si eres nuevo en Vue, la serie de introducción de Sarah es un buen lugar para comenzar. También vale la pena señalar que vincularé los documentos de Vue 2 a lo largo de esta publicación. Vue 3 se encuentra actualmente en versión beta y sus documentos están sujetos a cambios.

Comenzamos a crear una plantilla básica para nuestro calendario. Podemos delinear nuestro marcado en tres capas donde tenemos:

  • Una sección para el encabezado del calendario. Esto mostrará los componentes con el mes seleccionado actualmente y los elementos responsables de la paginación entre meses.
  • Una sección para el encabezado de la cuadrícula del calendario. Encabezado de tabla que contiene una lista que contiene los días de la semana, comenzando por el lunes.
  • La cuadrícula del calendario. Ya sabes, cada día del mes actual, representado como un cuadrado en la cuadrícula.

Escribamos esto en un archivo llamado CalendarMonth.vue. Este será nuestro componente principal.

 

!-- CalendarMonth.vue --template !-- Parent container for the calendar month -- div !-- The calendar header -- div !-- Month name -- CalendarDateIndicator / !-- Pagination -- CalendarDateSelector / /div !-- Calendar grid header -- CalendarWeekdays / !-- Calendar grid -- ol CalendarMonthDayItem / /ol /div/template

Ahora que tenemos algunas marcas con las que trabajar, vayamos un paso más allá y creemos los componentes necesarios.

Paso 2: componentes del encabezado

En nuestro encabezado tenemos dos componentes:

  • CalendarDateIndicatormuestra el mes seleccionado actualmente.
  • CalendarDateSelectores responsable de paginar entre meses.

Empecemos con CalendarDateIndicator. Este componente aceptará una selectedDatepropiedad que es un objeto Day.js que formateará la fecha actual correctamente y se la mostrará al usuario.

!-- CalendarDateIndicator.vue --template div{{ selectedMonth }}/div/templatescriptexport default { props: { selectedDate: { type: Object, required: true } }, computed: { selectedMonth() { return this.selectedDate.format("MMMM YYYY"); } }};/script

Eso fue fácil. Vamos a crear el componente de paginación que nos permite navegar entre meses. Contendrá tres elementos encargados de seleccionar el mes anterior, actual y siguiente. Agregaremos un detector de eventos en aquellos que activan el método apropiado cuando se hace clic en el elemento.

!-- CalendarDateSelector.vue --template div span @click="selectPrevious"﹤/span span @click="selectCurrent"Today/span span @click="selectNext"﹥/span /div/template

Luego, en la sección del script, configuraremos dos accesorios que el componente aceptará:

  • currentDatenos permite volver al mes actual cuando se hace clic en el botón “Hoy”.
  • selectedDateNos dice qué mes está seleccionado actualmente.

También definiremos métodos responsables de calcular la nueva fecha seleccionada en función de la fecha seleccionada actualmente utilizando los métodos subtracty addde Day.js. Cada método también envía $emitun evento al componente principal con el mes recién seleccionado. Esto nos permite mantener el valor de la fecha seleccionada en un lugar (que será nuestro CalendarMonth.vuecomponente) y pasarlo a todos los componentes secundarios (es decir, encabezado, cuadrícula de calendario).

// CalendarDateSelector.vuescriptimport dayjs from "dayjs";export default { name: "CalendarDateSelector", props: { currentDate: { type: String, required: true }, selectedDate: { type: Object, required: true } }, methods: { selectPrevious() { let newSelectedDate = dayjs(this.selectedDate).subtract(1, "month"); this.$emit("dateSelected", newSelectedDate); }, selectCurrent() { let newSelectedDate = dayjs(this.currentDate); this.$emit("dateSelected", newSelectedDate); }, selectNext() { let newSelectedDate = dayjs(this.selectedDate).add(1, "month"); this.$emit("dateSelected", newSelectedDate); } }};/script

Ahora, volvamos al CalendarMonth.vuecomponente y usamos nuestros componentes recién creados.

 

Para usarlos primero necesitamos importar y registrar los componentes, también necesitamos crear los valores que pasarán como accesorios a esos componentes:

  • today formatea correctamente la fecha de hoy y se utiliza como valor para el botón de paginación “Hoy”.
  • selectedDate es la fecha seleccionada actualmente (establecida en la fecha de hoy de forma predeterminada).

Lo último que debemos hacer antes de poder renderizar los componentes es crear un método que sea responsable de cambiar el valor de selectedDate. Este método se activará cuando se reciba el evento del componente de paginación.

// CalendarMonth.vuescriptimport dayjs from "dayjs";import CalendarDateIndicator from "./CalendarDateIndicator";import CalendarDateSelector from "./CalendarDateSelector";export default { components: { CalendarDateIndicator, CalendarDateSelector }, data() { return { selectedDate: dayjs(), today: dayjs().format("YYYY-MM-DD") }; }, methods: { selectDate(newSelectedDate) { this.selectedDate = newSelectedDate; } }};/script

Ahora tenemos todo lo que necesitamos para representar el encabezado de nuestro calendario:

!-- CalendarMonth.vue --template div div CalendarDateIndicator :selected-date="selectedDate" / CalendarDateSelector :current-date="today" :selected-date="selectedDate" @dateSelected="selectDate" / /div /div/template

Éste es un buen lugar para detenerse y ver lo que tenemos hasta ahora. Nuestro encabezado de calendario hace todo lo que queremos, así que avanzamos y creemos componentes para nuestra cuadrícula de calendario.

Paso 3: componentes de la cuadrícula del calendario

Aquí, nuevamente, tenemos dos componentes:

  • CalendarWeekdaysmuestra los nombres de los días de la semana.
  • CalendarMonthDayItemrepresenta un solo día en el calendario.

El CalendarWeekdayscomponente contiene una lista que registra en iteración las etiquetas de los días de la semana (usando la v-fordirectiva) y representa esa etiqueta para cada día de la semana. En la sección del script, debemos definir nuestros días de la semana y crear una computedpropiedad para que esté disponible en la plantilla y almacenar en caché el resultado para evitar que tengamos que volver a calcularlo en el futuro.

// CalendarWeekdays.vuetemplate ol li v-for="weekday in weekdays" :key="weekday" {{ weekday }} /li /ol/template
scriptconst WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];export default { name: 'CalendarWeekdays', computed: { weekdays() { return WEEKDAYS } }}/script

El siguiente es CalendarMonthDayItem. Es un elemento de lista que recibe una daypropiedad que es un objeto y una propiedad booleana, isTodayque nos permite diseñar el elemento de la lista para indicar que es la fecha actual. También tenemos una computedpropiedad que formatea el objeto del día recibido en nuestro formato de fecha deseada ( Do el día numérico del mes).

 

// CalendarMonthDayItem.vuetemplate li :class="{ 'calendar-day--not-current': !isCurrentMonth, 'calendar-day--today': isToday }" span{{ label }}/span /li/template
scriptimport dayjs from "dayjs";export default { name: "CalendarMonthDayItem", props: { day: { type: Object, required: true }, isCurrentMonth: { type: Boolean, default: false }, isToday: { type: Boolean, default: false } }, computed: { label() { return dayjs(this.day.date).format("D"); } }};/script

Bien, ahora que tenemos estos dos componentes, veamos cómo podemos agregarlos a nuestro CalendarMonthcomponente.

Primero necesitamos importarlos y registrarlos. También necesitamos crear una computedpropiedad que devolverá una serie de objetos que representan nuestros días. Cada día contiene una datepropiedad y isCurrentMonthuna propiedad. Mejores Opiniones y reviews

// CalendarMonth.vuescriptimport dayjs from "dayjs";import CalendarMonthDayItem from "./CalendarMonthDayItem";import CalendarWeekdays from "./CalendarWeekdays";
export default { name: "CalendarMonth", components: { // ... CalendarMonthDayItem, CalendarWeekdays }, computed: { days() { return [ { date: "2020-06-29", isCurrentMonth: false }, { date: "2020-06-30", isCurrentMonth: false }, { date: "2020-07-01", isCurrentMonth: true }, { date: "2020-07-02", isCurrentMonth: true }, // ... { date: "2020-07-31", isCurrentMonth: true }, { date: "2020-08-01", isCurrentMonth: false }, { date: "2020-08-02", isCurrentMonth: false } ]; } }};/script

Luego, en la plantilla, podemos renderizar nuestros componentes. Nuevamente, usamos la v-fordirectiva para representar la cantidad requerida de elementos del día.

!-- CalendarMonth.vue --template div div // ... /div CalendarWeekdays/ ol CalendarMonthDayItem v-for="day in days" :key="day.date" :day="day" :is-today="day.date === today" / /ol /div/template

Bien, las cosas empiezan un verso bien ahora. Eche un vistazo a dónde estamos. Se ve bien pero, como probablemente habrás notado, la plantilla solo contiene datos estáticos por el momento. El mes está codificado como julio y los números de los días también están codificados. Cambiaremos eso calculando qué fecha debe mostrarse en un mes específico. ¡Vamos a sumergirnos en el código!

Paso 4: configurar el calendario del mes actual

Pensemos cómo podemos calcular la fecha que debe mostrarse en un mes específico. Ahí es donde realmente entra en el juego Day.js. Proporciona todos los datos que necesitamos para colocar correctamente las fechas en los días correctos de la semana para un mes determinado utilizando datos reales del calendario. Nos permite obtener y configurar cualquier cosa, desde la fecha de inicio de un mes hasta todas las opciones de formato de fecha que necesitamos para mostrar los datos.

 

Lo haremos:

  • Obtener el mes actual
  • Calcular dónde se deben colocar los días (días laborables)
  • Calcular los días para mostrar las fechas del mes anterior y siguiente.
  • Pon todos los días juntos en una sola matriz.

Ya tenemos Day.js importado en nuestro CalendarMonthcomponente. También nos apoyaremos en un par de complementos de Day.js para obtener ayuda. WeekDay nos ayuda a establecer el primer día de la semana. Algunos prefieren el domingo como primer día de la semana. Otros prefieren el lunes. Diablos, en algunos casos, tiene sentido comenzar el viernes. Vamos a empezar el lunes.

El complemento WeekOfYear devuelve el valor numérico de la semana actual entre todas las semanas del año. Hay 52 semanas en un año, por lo que diríamos que la semana que comienza el 1 de enero es la primera semana del año, y así sucesivamente.

Esto es lo que ponemos CalendarMonth.vuepara poner todo eso en uso:

// CalendarMonth.vuescriptimport dayjs from "dayjs";import weekday from "dayjs/plugin/weekday";import weekOfYear from "dayjs/plugin/weekOfYear";// ...
dayjs.extend(weekday);dayjs.extend(weekOfYear);// ...

Eso fue bastante sencillo, pero ahora comienza la verdadera diversión, ya que jugaremos con la cuadrícula del calendario. Detengámonos por un segundo y pensemos qué es lo que realmente debemos hacer para hacerlo bien.

Primero, queremos que los números de fecha caigan en las columnas correctas de los días de la semana. Por ejemplo, el 1 de julio de 2020 es miércoles. Ahí es donde debería comenzar la numeración de fechas.

Si el primero del mes cae en miércoles, eso significa que tendremos elementos de cuadrícula vacíos para el lunes y martes de la primera semana. El último día del mes es el 31 de julio, que cae en viernes. Eso significa que el sábado y el domingo estarán vacíos en la última semana de la parrilla. Queremos llenarlos con las fechas iniciales y finales del mes anterior y siguiente, respectivamente, para que la cuadrícula del calendario esté siempre llena.

Agregar fechas para el mes actual

Para agregar los días del mes actual a la cuadrícula, necesitamos saber cuántos días existen en el mes actual. Podemos conseguirlo utilizando el daysInMonthmétodo proporcionado por Day.js. Creemos una computedpropiedad para eso.

// CalendarMonth.vuecomputed: { // ... numberOfDaysInMonth() { return dayjs(this.selectedDate).daysInMonth(); }}

Cuando sabemos eso, creamos una matriz vacía con una longitud igual a la cantidad de días del mes actual. Luego hacemos map()esa matriz y creamos un objeto de día para cada uno. El objeto que creamos tiene una estructura arbitraria, por lo que puedes agregar otras propiedades si las necesitas.

Sin embargo, en este ejemplo necesitamos una datepropiedad que se usará para verificar si una fecha en particular es el día actual. También devolveremos un isCurrentMonthvalor que verifica si la fecha está en el mes actual o fuera de él. Si está fuera del mes actual, les aplicaremos un estilo para que la gente sepa que están fuera del rango del mes actual.

// CalendarMonth.vuecomputed: { // ... currentMonthDays() { return [...Array(this.numberOfDaysInMonth)].map((day, index) = { return { date: dayjs(`${this.year}-${this.month}-${index + 1}`).format("YYYY-MM-DD") isCurrentMonth: true }; }); },}

Agregar fechas del mes anterior

Para que las fechas del mes anterior se muestren en el mes actual, debemos verificar cuál es el día de la semana del primer día en el mes seleccionado. Ahí es donde podemos usar el complemento WeekDay para Day.js. Creemos un método auxiliar para eso.

// CalendarMonth.vuemethods: { // ... getWeekday(date) { return dayjs(date).weekday(); },}

Luego, en base a eso, debemos verificar qué día fue el último lunes del mes anterior. Necesitamos ese valor para saber cuántos días del mes anterior deben ser visibles en la vista del mes actual. Podemos obtenerlo restando el valor del día de la semana del primer día del mes actual. Por ejemplo, si el primer día del mes es miércoles, debemos restar tres días para obtener el último lunes del mes anterior. Tener ese valor nos permite crear una serie de objetos de día desde el último lunes del mes anterior hasta el final de ese mes.

// CalendarMonth.vuecomputed: { // ... previousMonthDays() { const firstDayOfTheMonthWeekday = this.getWeekday(this.currentMonthDays[0].date); const previousMonth = dayjs(`${this.year}-${this.month}-01`).subtract(1, "month"); // Cover first day of the month being sunday (firstDayOfTheMonthWeekday === 0) const visibleNumberOfDaysFromPreviousMonth = firstDayOfTheMonthWeekday ? firstDayOfTheMonthWeekday - 1 : 6; const previousMonthLastMondayDayOfMonth = dayjs(this.currentMonthDays[0].date).subtract(visibleNumberOfDaysFromPreviousMonth, "day").date(); return [...Array(visibleNumberOfDaysFromPreviousMonth)].map((day, index) = { return { date: dayjs(`${previousMonth.year()}-${previousMonth.month() + 1}-${previousMonthLastMondayDayOfMonth + index}`).format("YYYY-MM-DD"), isCurrentMonth: false }; }); }}

Agregar fechas del próximo mes

Ahora, hagamos lo contrario y calculemos qué días necesitamos del próximo mes para completar la cuadrícula del mes actual. Afortunadamente, podemos utilizar el mismo asistente que acabamos de crear para el cálculo del mes anterior. La diferencia es que calcularemos cuántos días del próximo mes deberían ser visibles restando el valor numérico del día de la semana de siete.

Entonces, por ejemplo, si el último día del mes es sábado, necesitamos restar un día de siete para construir una serie de fechas necesarias del próximo mes (domingo).

// CalendarMonth.vuecomputed: { // ... nextMonthDays() { const lastDayOfTheMonthWeekday = this.getWeekday(`${this.year}-${this.month}-${this.currentMonthDays.length}`); const nextMonth = dayjs(`${this.year}-${this.month}-01`).add(1, "month"); const visibleNumberOfDaysFromNextMonth = lastDayOfTheMonthWeekday ? 7 - lastDayOfTheMonthWeekday : lastDayOfTheMonthWeekday; return [...Array(visibleNumberOfDaysFromNextMonth)].map((day, index) = { return { date: dayjs(`${nextMonth.year()}-${nextMonth.month() + 1}-${index + 1}`).format("YYYY-MM-DD"), isCurrentMonth: false }; }); }}

Bien, sabemos cómo crear todos los días que necesitamos, así que usémoslos y fusionemos todos los días en una única matriz de todos los días que queremos mostrar en el mes actual, incluidas las fechas de relleno del mes anterior y siguiente.

// CalendarMonth.vuecomputed: { // ... days() { return [ ...this.previousMonthDays, ...this.currentMonthDays, ...this.nextMonthDays ]; },}

¡Voilá, ahí lo tenemos! Echa un vistazo a la demostración final para ver todo junto.






SUSCRÍBETE A NUESTRO BOLETÍN 

No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.










Al suscribirte, aceptas nuestra política de privacidad y nuestros términos de servicio.






Tal vez te puede interesar:

  1. La innovación no puede mantener la Web rápida
  2. Rendimiento web ultrarrápido
  3. Tabla de contenidos fijos con estados activos de desplazamiento
  4. “cambiar tamaño: ninguno;” en áreas de texto es una mala experiencia de usuario

Hagamos un calendario mensual con tecnología Vue

Hagamos un calendario mensual con tecnología Vue

Paso 1: comenzar con el marcado básicoPaso 2: componentes del encabezadoPaso 3: componentes de la cuadrícula del calendarioPaso 4: configurar el calendario d

programar

es

https://aprendeprogramando.es/static/images/programar-hagamos-un-calendario-mensual-con-tecnologia-vue-1688-0.jpg

2024-06-13

 

Hagamos un calendario mensual con tecnología Vue
Hagamos un calendario mensual con tecnología Vue

Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

 

 

Update cookies preferences