No es una buena idea usar jQuery y Vue.js en la misma interfaz. No lo hagas si puedes evitarlo, pero probablemente si estás leyendo esto no porque quieras usar jQuery y Vue juntos, sino porque tienes que hacerlo. Tal vez un cliente insiste en usar un plugin de jQuery en particular y no hay tiempo para reescribirlo para Vue.
Si tienes cuidado de cómo lo haces, puedse usar jQuery y Vue juntos de forma segura. En este artículo vamos a demostrar cómo añadir el plugin jQuery UI Datepicker a un proyecto Vue.
Y para presumir un poco, incluso vamos a enviar datos entre este plugin jQuery y Vue!
El problema de usar jQuery y Vue juntos
¿Por qué es potencialmente peligroso hacer esto?
Vue es una biblioteca celosa en el sentido de que debes dejar que posea completamente el trozo de DOM que le des (definido por lo que le pases a el
). Si jQuery realiza un cambio en un elemento que Vue está gestionando, por ejemplo, añade una clase a algo, Vue no se dará cuenta del cambio y lo sobrescribirá en el siguiente ciclo de actualización.
Solución: utilizar un componente como wrapper
Sabiendo que Vue y jQuery nunca van a compartir parte del DOM, tenemos que decirle a Vue que acordone un área y se la entregue a jQuery.
Usar un componente para envolver un plugin de jQuery parece ser el camino a seguir porque:
- Podemos utilizar ganchos de ciclo de vida para el montaje y desmontaje del código jQuery
- Podemos usar la interfaz de componentes para comunicarnos con el resto de la aplicación Vue a través de accesorios y eventos.
- Los componentes pueden optar por no participar en las actualizaciones con
v-once
Configurar jQuery UI Datepicker
Obviamente, primero debes incluir las bibliotecas jQuery y jQuery UI en tu proyecto. Una vez que los tengas, el selector de fechas sólo necesita un elemento de input
al que conectarse:
Date: <input id="datepicker"/>
A continuación, se puede instanciar seleccionándolo y llamando al método:
$('#datepicker').datepicker();
El componente Datepicker
Para hacer nuestro componente datepicker, la plantilla será el siguiente elemento de input
:
Vue.component('date-picker', function() { template: '<input/>' }); new Vue({ el: '#app' });
<div id="app"> Date: <date-picker></date-picker></div>
Nota: este componente no debe ser más que una envoltura (wrapper) para el plugin. No fuerces tu suerte y le des propiedades de datos o utilices directivas o slots.
Instanciación del widget
En lugar de dar a nuestra input
un ID y seleccionarlo, podemos usar this.$el
, ya que cada componente puede acceder a su propio nodo raíz de esa manera. El nodo raíz será, por supuesto, la input
.
Luego podemos envolver la referencia del nodo en un selector jQuery para acceder al método datepicker
,es decir $(this.$el).datepicker()
.
Ten en cuenta que utilizamos el hook (gancio) del ciclo de vida mounted
(montado) ya que this.$el
es indefinido hasta que se monta el componente.
Vue.component('date-picker', function() { template: '<input/>', mounted: function() { $(this.$el).datepicker(); } });
Desmontaje
Para desmontar el datepicker podemos seguir un enfoque similar y utilizar un hook (gancho) de lifecycle (ciclo de vida). Tenga en cuenta que debemos usar beforeDestroy
para asegurarnos de que nuestra entrada está todavía en el DOM y por lo tanto puede ser seleccionada (no está definida en el hook (gancho) de destroy
).
Vue.component('date-picker', { template: '<input/>', mounted: function() { $(this.$el).datepicker(); }, beforeDestroy: function() { $(this.$el).datepicker('hide').datepicker('destroy'); } });
Passar configuración con props
Para que nuestro componente sea reutilizable, sería bueno permitir una configuración personalizada, como especificar el formato de fecha con la propiedad de configuración dateFormat
. Podemos hacerlo con props
:
Vue.component('date-picker', { template: '<input/>', props: [ 'dateFormat' ], mounted: function() { $(this.$el).datepicker({ dateFormat: this.dateFormat }); }, beforeDestroy: function() { ... } });
<div id="app"><date-picker date-format="yy-mm-dd"></date-picker></div>
Dejar que jQuery maneje las actualizaciones
Digamos que, en lugar de pasar el prop dateFormat
como una cadena, lo convertiste en una propiedad data
de tu instancia raíz, es decir:
var vm = new Vue({ data: { ... dateFormat: 'yy-mm-dd' } });
<div id="app"><date-picker date-format="dateFormat"></date-picker></div>
Esto significaría que dateFormat
sería una propiedad de datos reactiva. Puede actualizar su valor en algún momento de la vida de su aplicación:
// change the date format to something new vm.dateFormat = 'yy-dd-mm';
Dado que la propriedad dateFormat
es una dependencia del hook mounted
(montado) del componente datepicker la actualización del mismo provocaría que el componente se volviera a renderizar. Esto no estaría bien. jQuery ya ha configurado su selector de fecha en la input
y ahora lo está manejando con sus propias clases personalizadas y oyentes de eventos. Una actualización del componente resultaría en el reemplazo de la input
y por lo tanto la configuración de jQuery se restablecería instantáneamente.
Tenemos que hacerlo de forma que los datos reactivos no puedan desencadenar una actualización en este componente....
v-once
La directiva v-once
se utiliza para almacenar en caché un componente en el caso de que tenga mucho contenido estático. Esto hace que el componente se excluya de las actualizaciones.
Esto es realmente perfecto para usar en nuestro componente plugin, ya que hará que Vue lo ignore. Esto nos da cierta confianza en que jQuery va a tener un control sin trabas sobre este elemento durante el ciclo de vida de la aplicación.
<div id="app"><date-picker date-format="yy-mm-dd"v-once></date-picker></div>
Pasar datos de jQuery a Vue
Sería bastante inútil tener un selector de fecha si no pudiéramos recuperar la fecha elegida y usarla en otro lugar de la aplicación. Hagámoslo de manera que después de que un valor es escogido, se imprima en la página.
Comenzaremos dando a nuestra instancia raíz una propiedad date
:
new Vue({ el: '#app', data: { date: null } });
<div id="app"><date-picker date-format="yy-mm-dd"v-once></date-picker><p>{{ date }}</p></div>
El widget datepicker tiene una llamada onSelect
que se llama cuando se escoge una fecha. Entonces podemos usar nuestro componente para emitir esta fecha a través de un evento personalizado:
mounted: function() { var self = this; $(this.$el).datepicker({ dateFormat: this.dateFormat, onSelect: function(date) { self.$emit('update-date', date); } }); }
Nuestra instancia raíz puede escuchar el evento personalizado y recibir la nueva fecha:
<div id="app"><date-picker @update-date="updateDate"date-format="yy-mm-dd"v-once></date-picker><p>{{ date }}</p></div>
new Vue({ el: '#app', data: { date: null }, methods: { updateDate: function(date) { this.date = date; } } });
Esto es todo, espero vuestros comentarios abajo!
Luigi Nori
He has been working on the Internet since 1994 (practically a mummy), specializing in Web technologies makes his customers happy by juggling large scale and high availability applications, php and js frameworks, web design, data exchange, security, e-commerce, database and server administration, ethical hacking. He happily lives with @salvietta150x40, in his (little) free time he tries to tame a little wild dwarf with a passion for stars.
Artículos relacionados
Crear PDF con Javascript y jsPDF
El formato PDF es muy útil para descargar datos de forma masiva en una aplicación web. Ayuda a los usuarios a descargar contenido dinámico en forma de archivo para que…
Como hacer tu propio cursor personalizado para tu web
Cuando empecé a ojear webs distintas y originales para aprender de ellas, de las primeras cosas que me llamaron la atención fue que algunas de ellas tenían sus propios cursores,…
Explorando la API de CSS Paint: Redondeo de formas parte 1
Añadir bordes a las formas complejas es un auténtico rollo (a veces), pero redondear las esquinas de las formas complejas es un suplicio jejeje. Por suerte, la API de pintura…
Cómo enviar un correo electrónico desde un formulario de contacto HTML
En el artículo de hoy vamos a escribir sobre cómo hacer un formulario que funcione y que al pulsar ese botón de envío sea funcional y envíe el correo electrónico…
Cómo hacer un sitio web multilingüe sin redireccionamiento
Hoy, vamos a hablar de cómo implementar un simple selector de idioma en el sitio web estático o básico, sin necesidad de ningún backend o llamadas a la base de…
Comenzando con Bootstrap-Vue paso a paso
Hoy te mostraremos cómo usar BootstrapVue, describiremos el proceso de instalación y mostraremos la funcionalidad básica. El proyecto está basado en el framework CSS más popular del mundo - Bootstrap, para…
Por qué los desarrolladores de JavaScript deberían preferir Axios a Fetch
Por qué los desarrolladores de JavaScript deberían preferir Axios a Fetch En mi artículo anterior, "Usando la Api Fetch Para Hacer Llamadas Ajax", hablé de los fundamentos de la API Fetch.…
Creación de un sencillo spinner-loader CSS
En el artículo de hoy mostraremos cómo animar un loader básico que gira cuando se define alguna acción predefinida, como cargar una imagen. Eso se puede utilizar en un sitio…
Los mejores selectores de fechas para Bootstrap y tu aplicación
Los selectores de fecha son widgets que permiten a los usuarios elegir una sola fecha o rango de fechas y horas. Es un elemento habitual para todo usuario de Internet,…
Validación de formularios HTML usando BULMA y vanilla JavaScript
Hoy vamos a escribir sobre los formularios de contacto y cómo validarlos usando JavaScript. El formulario de contacto parece ser una de las características principales de toda página web básica. Es…
Cómo usar el efecto Parallax.Js en tu sitio web
Hoy vamos a escribir sobre el efecto de parallax, similar al desplazamiento de parallax, y cómo implementarlo para mejorar su página de aterrizaje. En webdev, dicen que primero el móvil…
Usando la API FETCH para hacer llamadas AJAX - Una promesa cumplida
En este artículo hablamos sobre lo que son las llamadas AJAX y cómo utilizarlas de forma tradicional, utilizando el objeto XMLHttpRequest (XHR). En resumen, gracias a las llamadas AJAX una…