Herramientas y prácticas para acelerar el proceso de desarrollo de Vue.js

- Estructuración de proyectos basada en módulos versus basada en archivos #
- Usar directivas personalizadas #
- Controlar las actualizaciones #
- Bibliotecas de terceros y optimización #
- Tomar decisiones tempranas para utilizar Vuex #
- Uso del método Proporcionar/Inyectar para pasar datos #
- Uso adecuado de accesorios para componentes del formulario #
- Familiarizarse con Vue Devtools #
- Herramientas para facilitar el trabajo en Vue
Aunque Vue.js afirma tener un marco minimalista accesible que puede adaptarse progresivamente, puede resultar un poco abrumador cuando se comienza como novato en Vue.js. En este artículo, buscamos formas de hacer que escribir Vue.js sea muy sencillo.
A lo largo de este tutorial, analizaremos las prácticas que se deben adoptar, las cosas que se deben evitar y veremos más de cerca algunas herramientas útiles para facilitar la escritura de Vue.js. Me centraré principalmente en Vue 2 ya que la mayoría de las personas y organizaciones todavía usan la versión anterior. Sin embargo, no hay razón para preocuparse, ya que la mayoría de las cosas mencionadas aquí todavía se aplican a Vue 3 , ya que es solo una versión más rápida y sobrealimentada. Aún así, si ya conoce Vue 2 y solo desea conocer las novedades de Vue 3, puede consultar la guía de migración para obtener más información.
Nota: Este artículo está dirigido tanto a principiantes como a desarrolladores experimentados que quieran mejorar sus habilidades con Vue.js. El conocimiento básico de JavaScript y Vue.js será de gran beneficio a medida que avance en este tutorial.
Estructuración de proyectos basada en módulos versus basada en archivos #
Comencemos viendo cómo estructurar archivos por módulos, cómo la estructuración basada en archivos puede no ser una buena idea cuando se trata de construir proyectos de escala y cómo estructurar módulos para que se ajusten a los requisitos del negocio.
Como estamos creando un proyecto recientemente con Vue.js CLI, obtenemos la estructura de archivos predeterminada que ha sido asignada por el equipo de Vue.js. Usar la estructura de archivos propuesta no es una mala manera de estructurar su proyecto per se, pero a medida que su proyecto crezca, necesitará una mejor estructura a medida que su código se agrupe y sea más difícil navegar y acceder a los archivos.
Aquí es donde entra en juego el método basado en módulos para estructurar su proyecto .
Una mala forma de estructurar su proyecto implicará almacenar diferentes datos que no están relacionados con la misma carpeta, como el componente de notificación y el componente de autenticación en la carpeta del componente raíz:
+-- src/| +-- assets/| +-- logo.png| +-- userprofile.png| +-- components| +-- NotificationBar.vue| +-- LoginForm.vue| +-- DashboardInfo.vue| +-- AuthenticationModal.vue| +-- main.js
Entonces, lo que queremos hacer es desacoplar el proyecto según la lógica empresarial y las preocupaciones para que tengamos algo como un módulo de autenticación, un módulo de producto, un módulo de servicio, etc. De esta manera podemos asegurarnos de que todo lo relacionado con esa característica en particular se incluya en el módulo, lo que hace que nuestro código sea más ordenado y la navegación no sea tan difícil.
+-- modules/| +-- AuthModule/| +-- assets/| +-- userprofile.png| +-- Components/| +-- Authentication.vue| +-- login.vue| +-- NotificationModule| +-- assets/| +-- Alert.png| +-- Components/| +-- NotificationBar.vue| +-- ProductModule/
Organización de módulos #
Hay dos formas de organizar sus módulos:
- Módulos principales de Vue.js,
- Módulos de funciones de la aplicación.
Los módulos principales de Vue.js están aquí para facilitar el desarrollo de Vue.js. Los módulos como el módulo de servicio que contiene todas las solicitudes de red que necesita la empresa se guardan en este módulo central y todas las solicitudes de red correspondientes se realizan desde aquí.
Modularizar su aplicación según las características es una excelente manera de crear una mejor estructura de archivos en su aplicación. Esto permitirá separar su inquietud y garantizará que solo esté trabajando en la función a la que usted o su equipo están asignados. Otra ventaja de la modularización según la función es su capacidad de mantenimiento y su capacidad para evitar deudas técnicas a largo plazo, cuando podría ser necesario volver a trabajar en la aplicación.
Ahora, siempre que sea necesario agregar, eliminar o cambiar el estado de una función en particular, todo lo que debemos hacer es navegar hasta esa función y realizar cambios sin interrumpir la aplicación. Este método de modularización permite un desarrollo eficiente del programa y una fácil depuración y modificación en nuestra aplicación.
Por ejemplo, una función de pago asignada a usted y a su equipo es un buen momento para implementar un payout
módulo que encapsule todas las funcionalidades y datos de la función.
+-- modules/| +-- payout/| +-- index.js| +-- assets/| +-- Components/| +-- PayOut.vue| +-- UserInfo.vue| +-- store/| +-- index.js | +-- actions.js| +-- mutations.js | +-- Test/
Según nuestra función de pago anterior, tenemos un index.js
archivo para importar y usar complementos asociados únicamente con el módulo de pago. La carpeta de activos alberga todos los activos (imágenes y estilos) del módulo. Nuestra carpeta de componentes contiene componentes relacionados con la función de pago. La carpeta de la tienda contiene nuestras acciones, mutaciones y captadores utilizados para administrar el estado de esta función. También hay una carpeta de prueba para realizar pruebas de esta función.
Usar directivas personalizadas #
Las directivas en Vue.js son una forma de decirle a Vue.js que haga algo o que muestre un determinado comportamiento por nosotros. Ejemplos de directivas son ,,, v-if
etc. En nuestra aplicación Vue.js, cuando usamos algo como v-model para vincular datos a una entrada en un formulario, le estamos dando al código Vue.js algunas instrucciones específicas que son peculiares de Vue. .js. Pero, ¿qué pasa si queremos una acción o comportamiento particular que nuestra directiva proporcionada por Vue.js no nos permite hacer? ¿Qué hacemos entonces? Podemos crear lo que llamamos directivas personalizadas.v-model
v-for
Registro de directivas personalizadas y ganchos de directivas #
Podemos proceder a registrar directivas de dos maneras:
- Globalmente
en nuestromain.js
archivo. - Localmente
en nuestro componente.
Los ganchos en las directivas son como métodos que se activan cuando ocurre una determinada acción en nuestras directivas. Al igual que los ganchos del ciclo de vida de los ganchos creados y montados , contamos con ganchos para usar en nuestras directivas.
Digamos que estamos creando una aplicación y en una de nuestras páginas queremos que el color de fondo cambie siempre cada vez que navegamos hacia ella. A esta directiva le vamos a llamar colorChange
. Podemos lograrlo con la ayuda de una directiva.
Nuestra plantilla se parece a esto:
template div id="app" v-color-change HelloWorld msg="Hello Vue in CodeSandbox!"/ /div/template
Podemos ver la directiva personalizada arriba, pero para que funcione, en nuestro main.js
archivo agregamos:
// custom directiveVue.directive("color-change", { bind: function (el) { const random = Math.floor(Math.random() * 900000) + 100000; el.style.backgroundColor = `#${random}` }})
La directiva Vue.js anterior toma el nombre de la directiva como primer argumento y luego Object
como segundo argumento que controla el comportamiento de las directivas. bind
es uno de los ganchos de los que hablamos y se llamará una vez que la directiva esté vinculada al elemento. Acepta los siguientes argumentos:
el
Este es el nodo del elemento al que hemos adjuntado la directiva.binding
Contiene propiedades útiles que cambian el comportamiento de la directiva.vnode
Este es el nodo virtual de Vue.js.
Hemos creado un conjunto aleatorio de números de 6 dígitos para poder usarlo para cambiar el código hexadecimal de nuestro estilo de color de fondo.
Mejores prácticas al redactar directivas personalizadas #
Hemos creado una directiva personalizada para lo anterior, pero debemos tomar nota de algunas cosas. Además el
, nunca modifique los argumentos de enlace y asegúrese de que sean de solo lectura porque los argumentos de enlace son objetos con métodos nativos que pueden causar efectos secundarios si se modifican. Si es necesario, utilice el conjunto de datos de Vue.js para compartir información entre enlaces.
Si utilizamos la compilación CLI de Vue.js, las directivas personalizadas deben estar en el main.js
archivo para que todos los .vue
archivos puedan tener acceso a él. El nombre de su directiva debe ser algo que resuene con lo que hace esa directiva en particular, muy descriptivo sobre la funcionalidad de la directiva.
Puedes ver y jugar más con el código en este codesandbox que he creado. También puede leer más sobre esto en los documentos de Vue .
Controlar las actualizaciones #
El sistema de reactividad de Vue.js es poderoso en el sentido de que detecta cosas que necesitan actualización y las actualiza sin que usted, como desarrollador, haga nada. Por ejemplo, volver a representar una página cada vez que navegamos hacia ella. En ocasiones, el caso puede ser diferente, ya que podríamos encontrarnos escribiendo código que requiera que fuercemos una actualización.
Nota: Si necesita forzar una actualización, lo cual es una rara ocasión, es posible que necesite comprender realmente la reactividad de Vue y cómo utilizar correctamente los accesorios para comunicar datos dinámicos.
Forzar una actualización #
En la mayoría de los casos, cuando el valor en el objeto de datos de vue cambia, la vista se vuelve a representar automáticamente, pero no siempre es así. Un caso clásico de nuestra vista, no volver a renderizar es cuando usamos a v-for
en nuestra plantilla para recorrer algunos datos en el objeto de datos y no agregamos un :key
valor en el v-for
bucle.
div v-for="item in itemsArray" :key="item"
Esto le da a Vue.js una forma de rastrear la identidad de cada nodo y volver a representar la vista para cualquier cambio.
Una situación poco común que puede hacer que fuercemos una actualización es si configuramos intencionalmente o accidentalmente un elemento de la matriz con el índice.
var app = new Vue({ data: { items: ['1', '2'] }})app.items[1] = '7' //vue does not notice any change
Hay diferentes formas de forzar una actualización o volver a renderizar. Algunas son muy malas prácticas, como el uso de v-if
para volver a representar la página cuando es falsa true
, y cuando es falsa, el componente desaparece y ya no existe. Esta es una mala práctica porque la plantilla nunca se destruye, sino que simplemente se oculta hasta que se pueda reutilizar.
template div v-if="show" button @click="rerender"re-render/button /div/template
script export default { data() { return { show: true, }; }, methods: { rerender() { this.show= false; this.$nextTick(() = { this.show = true; }); } } };/script
En el código anterior, el estado de show
se establece inicialmente en verdadero, lo que significa que nuestro componente se representa inicialmente. Luego, cuando hacemos clic en el botón, rerender(
se llama a la función) y el estado de show
se establece en false
y el componente ya no se representa. En el siguiente tick, que es un ciclo único de actualización de DOM, show
se establece en true
y nuestro componente se representa nuevamente. Esta es una forma muy complicada de volver a renderizar.
Me gustaría hablar sobre dos formas legítimas de hacer esto:
- Vue's
$forceUpdate
. - Patrón de cambio de clave.
Vue $forceUpdate
: en el uso de $forceUpdate
, los componentes secundarios no se representan, solo la instancia de Vue.js, la instancia y los componentes secundarios con ranuras.
Globalmente podemos forzar la actualización:
import Vue from 'vue';Vue.forceUpdate();
Y localmente también:
export default { methods: { methodThatForcesUpdate() { this.$forceUpdate(); } }}
Usar el patrón de cambio de clave , que es mucho mejor que el $forceUpdate
método, es otra forma de hacerlo. La razón por la que el patrón de cambio de clave es mejor es que permite a Vue.js saber qué componente está vinculado a datos específicos y cuando la clave cambia, destruye el componente antiguo para crear uno nuevo, según matthiasg en este problema de Github. Me encontré con. Puede utilizar un :key
atributo para que Vue.js sepa qué componente está adjunto a un dato específico. Cuando la clave cambia, hace que Vue.js destruya el componente antiguo y se cree uno nuevo.
template Child :key="key" //templatescript export default { data() { return { key: 0, }; }, methods: { forceRerender() { this.key += 1; } } }/script
- Aproveche la sólida recuperación de datos y el tamaño de paquete optimizado con KendoReact Server Data Grid Probar ahora
Bibliotecas de terceros y optimización #
Es casi inevitable que no utilicemos bibliotecas de terceros en nuestras aplicaciones. Las bibliotecas de terceros pueden empezar a ser un problema si hacemos la vista gorda, aumentando el tamaño del paquete y ralentizando nuestra aplicación.
Recientemente utilicé la biblioteca de componentes de Vuetify en un proyecto y verifiqué que el tamaño total del paquete era de 500 kb minimizado. Cosas como esta pueden convertirse en un cuello de botella en nuestra aplicación. Puede verificar el tamaño del paquete de su aplicación usando webpack-bundle-analyzer
. Puedes instalarlo ejecutando:
npm install --save-dev webpack-bundle-analyzer
e inclúyalo en el archivo de configuración de su paquete web:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = { plugins: [ new BundleAnalyzerPlugin() ]}
Buenas prácticas para optimizar su aplicación Vue #
- Nuestro paquete principal solo debe contener dependencias que sean críticas para nuestra aplicación, como
vue
,.vuex
Deberíamos evitar colocar bibliotecas que se utilizan en rutas específicas de nuestra aplicación en el paquete principal. - Al utilizar bibliotecas de componentes, puede importar componentes individuales desde las bibliotecas, en lugar de importar todo. Por ejemplo, vuetificar:
template v-app v-navigation-drawer app !-- -- /v-navigation-drawer v-app-bar app !-- -- /v-app-bar /v-app/templatescriptimport { VApp, VNavigationDrawer, VAppBar } from 'vuetify/lib'export default { components: { VApp, VNavigationDrawer, VAppBar, }}/script
Al hacer lo anterior, hemos reducido el tamaño del paquete y el código redundante, usando solo los componentes que queremos usar en esa ruta en particular.
Tomar decisiones tempranas para utilizar Vuex #
A menudo me pregunto si debería iniciar un proyecto con Vuex. A veces solo quiero comenzar un pequeño proyecto paralelo y lo inicio sin Vuex para administrar mi estado y la comunicación usando accesorios comienza a complicarse.
Entonces, ¿cuándo deberíamos usar Vuex? Para responder a esto, debemos considerar:
- Tamaño del proyecto,
- La simplicidad del código,
- enrutamiento,
- Conjunto de datos involucrado,
- Anidamiento de componentes.
Si tu aplicación comienza a crecer, solo es apropiado incluir Vuex para administrar el estado de tu aplicación. Si alguna vez tiene dudas sobre si debe utilizar un administrador estatal al iniciar su proyecto, úselo. Sin embargo, se habla de que la nueva API de composición de Vue3 reemplazará a vuex.
Cómo se debe configurar Vuex para aplicaciones grandes #
Tenemos cuatro componentes en la tienda vuex:
- Estado : Almacenar datos en nuestra tienda.
- Getters : recupera datos de estado.
- Mutaciones : se utiliza para mutar datos de estado.
- Acción : Se utiliza para cometer mutaciones.
Cuando usamos lo anterior en Vuex debemos tener en cuenta que las acciones siempre deben cometer mutaciones pase lo que pase. Esto permite que nuestras herramientas de desarrollo puedan rastrear los cambios y volver a un período particular en nuestro estado y se deben llevar a cabo operaciones asincrónicas o lógica de negocios en las acciones.
Puede crear un archivo separado para cada uno de los componentes de Vuex con el siguiente aspecto:
├── services├── main.js└── store ├── index.js ├── actions.js ├── mutations.js └── Getters.js├── components
Modulación según la característica #
Si nuestro proyecto es muy grande con un equipo, podemos modularizar nuestra tienda según las características de la aplicación. Esto se hace especialmente cuando hay proyectos grandes y complejos con muchos archivos y carpetas y solo queremos una forma organizada de manejar la estructuración de nuestra aplicación. Tenemos que tener cuidado con la forma en que abordamos esto; de lo contrario, podemos hacer más daño que bien. Una tienda simple modularizada según la característica se ve así:
store/ ├── index.js └── modules/ ├── cart ├── index.js ├── actions.js ├── mutations.js ├── product.js ├── login.js
Buenas prácticas al utilizar módulos Vuex #
A medida que los módulos que hemos creado se vuelven más complicados, se vuelve más difícil importarlos y organizarlos manualmente. Se recomienda que sus módulos tengan un index.js
archivo en la raíz de su módulo, reuniendo todos los archivos.
Asegúrese de tener un patrón de nomenclatura estándar en su tienda, ya que esto aumentará la capacidad de mantenimiento. Puede usar camelCase para nombrar los módulos y luego una .store.js
extensión. Ejemplo: CartData.store.js
.
modules/ ├── cart.js ├── index.js - auto export module ├── userProduct.store.js ├── userData.store.js
El código relacionado con la lógica empresarial o el código asíncrono no debe ejecutarse dentro de mutaciones debido a su comportamiento de bloqueo; en su lugar, deben usarse acciones. Se considera una buena práctica no acceder directamente a un objeto de estado. En su lugar, utilice la función getter porque se puede asignar a cualquier componente de vue utilizando el mapGetters
comportamiento como una propiedad calculada con el resultado del getter almacenado en caché en función de sus dependencias. Además, asegúrese de que cada módulo tenga un espacio de nombres y de no acceder a ellos utilizando el alcance del estado global.
Uso del método Proporcionar/Inyectar para pasar datos #
Piensa en una aplicación que tiene diferentes componentes. Tenemos el componente principal y el componente principal tiene muchos componentes secundarios. En la imagen a continuación, vemos nuestro componente secundario A, B y D como componentes principales, luego vemos el componente E anidado en el componente D y el componente F anidado en el componente E. ¿Qué pasa si tenemos datos de la aplicación (como la dirección del usuario), que queremos usar en los componentes secundarios A, C y F, y estos datos de dirección de usuario están en nuestro componente principal.
Para hacer esto, necesitamos:
- Proporcionar valor en el componente principal (proveedor de dependencia).
- Inyecte el valor en el componente F (consumidor de dependencia).
En nuestro componente principal proporcionamos los datos:
app.component('parent-component', { data() { return { user: {name:"Uma Victor", address:"No 33 Rumukwurushi"} } }, provide() { return { userAddress: this.user.address } }, template: ` ... `})
Usamos provide
como función devolviendo un objeto para acceder a las propiedades de la instancia del componente.
En nuestro child-f
componente tenemos lo siguiente:
app.component('child-f', { inject: ['userAddress'], template: ` h2Injected property: {{ this.userAddress }}/h2 `})
Sin embargo, notamos que si cambiamos user.address
a otra dirección, el cambio no se reflejará en nuestro valor inyectado, esto se debe a que los datos proporcionados para proporcionar/inyectar no son reactivos inicialmente. Podemos solucionar este problema pasando un reactive
objeto a provide
. Tenemos que asignar una propiedad calculada a nuestro objeto de usuario.
app.component('parent-component', { data() { return { user: {name:"Uma Victor", address:"No 33 Rumukwurushi"} } }, provide() { return { userAddress: Vue.computed(() = this.user) } }, template: ` ... `})
Este patrón puede resultar muy útil y más sencillo que usar Vuex.
Sin embargo, con Vue3 y la reciente actualización, ahora podemos usar proveedores de contexto, lo que nos permite compartir datos entre múltiples componentes como vuex.
Uso adecuado de accesorios para componentes del formulario #
Crear formularios en la web es una de esas cosas que no a todos les encanta hacer. Vue.js facilita la creación de formularios excelentes. Para lograr esto necesitamos saber cómo usar correctamente los accesorios en los componentes de nuestro formulario. En una aplicación tradicional donde tenemos registro, inicios de sesión o página de producto, queremos tener un comportamiento y diseño consistentes. Por ejemplo, la página de inicio de sesión a continuación.
Con el código:
template div class="form-group" form label for="email"Your Name/label input type="text" id="name" class="form-control" placeholder="name" v-model="userData.name" / label for="email"Your Email Address/label input type="text" id="email" class="form-control" placeholder="Email" v-model="userData.email" / label for="email"Your Password/label input type="text" id="password" class="form-control" placeholder="password" v-model="userData.password" / /form /div/templatescript export default { data() { return { userData: { name: '', email: '', password: '' } } }, }/script
Nos gustaría tener un BaseInput
componente que podamos usar para las tres entradas del formulario anteriores. Nuestro BaseInput
se ve así:
template div label v-if="label"{{ label }}/label input type="email" @value="value" @input="updateInput" v-bind="$attrs" /div/templatescript export default { props: { label: { type: String, default: "" }, value: [String, Number] }, methods: { updateInput(event) { this.$emit('input', event.target.value) } } }/script
Queremos BaseInput
que aceptemos un label
accesorio que siempre es una cadena, y si la Entrada tiene una etiqueta, la mostramos en nuestra plantilla como podemos ver arriba.
When we fill the form, the updateInput
method is triggered. The updateInput
method takes the input event as an argument and it emits an event with the name of Input, along with the payload event.target.value
which is the name (John Doe) in the form:
BaseInput label="Your Name" v-model="userData.name" placeholder="Name"/
The v-model
will be listening for the input event and then when it gets it, it sets our userData.name
to the payload it got.
If we want to set a placeholder for an input, we might experience an error, this is because in vue2 attributes always attach themselves to the parent, so to fix this we set inheritAttrs
to false
and bind attrs
.
script export default { inheritAttrs: false, props: { label: { type: String, default: "" }, value: [String, Number] }, methods: { updateInput(event) { this.$emit('input', event.target.value) } } }/script
To where we want the placeholder attribute to be. Our form page code looks like this now:
template div class="form-group" form BaseInput label="Your Name" v-model="userData.name" placeholder="Name"/ BaseInput label="Your Email Address" v-model="userData.email" placeholder="Email"/ BaseInput label="Your Password" v-model="userData.password" placeholder="Password"/ /form /div/template
We finally have a standalone reusable form component. You can play with the code in the codesandbox I made.
Note: $Attrs
in Vue3 now includes all of your listeners, style bindings, and classes.
Familiarizarse con Vue Devtools #
Vue.js Devtools is a very powerful tool as it helps us effectively debug our application in real-time. It is most powerful when we use Vuex and we have to manage mutations and track changes in our app. Most Vue.js developers use devtools as an extension, but we can also install it as a standalone app.
Note: The Vue.js devtools only work in the development mode of your build and won’t work in production so other people can’t use it to inspect your app.
Instalación de Devtools como aplicación independiente
You might be wondering why we would want to install a standalone app for devtools when we can use the browser extension for it? It is because when you install it as a standalone app locally, you can use it from any browser.
We install it:
// Globallynpm install -g @vue/devtools// or locallynpm install --save-dev @vue/devtools
Once it’s done installing, run:
vue-devtools
Then in our index.html
file, located in the public folder in the root of our Vue.js application we add:
script src="https://localhost:8098"/script
Once your app is reloaded, it will automatically connect.
Algunas operaciones que podemos realizar con Vue Devtools #
Here are some helpful operations you can do on Vue.js DevTools.
- Dark Theme
In the new DevTools, there is now an option to set between light, dark, or contrast themes. You can do this by going to your global settings and selecting it.
- Timeline
The new timeline in the devtools displays information about events that occur and it’s arranged in chronological order. It is located next to the inspector and settings view.
- Format component name
You can choose to display your component name in either camelCase or kebab-case.
There are many other operations that you can utilize in the vue devtools. You can check out their changelog.
Herramientas para facilitar el trabajo en Vue
When working with Vuejs, we might encounter some features we would love to implement, but it might take a lot of time to hard code or just a little bit difficult to implement. As professional developers, we add certain tools and
Deja un comentario