Errores comunes en Vue
1. Omitir index en los v-for
Section titled “1. Omitir index en los v-for”<script setup lang="ts">import { suffle } from "lodash";import { ref } from "vue";
const items = ref([ { id: 1, label: "first name" }, { id: 2, label: "last name" }, { id: 3, label: "email" }, { id: 4, label: "website" },]);
function suffleItems() { items.value = suffle(items.value);}</script><template> <ul> <li v-for="item in items"> {{ item.label }} <input type="text" /> </li> </ul> <button @click="suffleItems">Shuffle</button></template>En este caso, se debe agregar el id en el v-for para que Vue pueda identificar cada item de la lista.
<li v-for="{ id, name } in items" :key="id"> {{ name }}</li><li v-for="({ id, name }, index) in items" :key="index"> {{ name }}</li>2. Prop drilling
Section titled “2. Prop drilling”El Prop drilling es un anti-patrón en el que el desarrollador pasa hacia abajo un prop a través de múltiples niveles de componentes simplemente para acceder a datos definidos más arriba en el árbol en un nivel profundamente anidado.
Codificar de esta manera puede llevar a un código difícil de mantener. Para evitar la perforación de props con provide/inject o mediante una solución de gestión de estado global.
3. Ver (watch) Arrays de la forma incorrecta
Section titled “3. Ver (watch) Arrays de la forma incorrecta”En el siguiente ejemplo, tenemos un watcher que se encarga de mostrar los cambios en un array.
<script setup lang="ts">import { ref, watch } from 'vue'const numbers = ref<number[]>([])
watch(numbers, () => console.log('New number added'))const addNumber = () => numbers.value.push(Math.random())</script>
<template> <button @click="addNumber">Add number</button></template>Pero si miramos en la consola, no aparece nada. El problema es que no estamos mirando el watch en profundidad usando el deep flag.
watch(numbers, () => console.log('New number added'), { deep: true })¿Por qué es necesario esto?
Section titled “¿Por qué es necesario esto?”Si estuvieramos remplazando el array en su totalidad no habría problema. Sin embargo, si estamos mutando el array, o un elemento del array, tenemos que usar el deep flag para que Vue pueda detectar los cambios.
4. ¿Ref o Reactive?
Section titled “4. ¿Ref o Reactive?”En el video se explica todo este tema con un ejemplo, pero para resumir, usar siempre ref
5. No mutar props
Section titled “5. No mutar props”Evitar siempre mutar props, ya que puede llevar a errores inesperados. Para ello, usar siempre un duplicado del prop.
5. Olvidar limpiar los event listeners manuales
Section titled “5. Olvidar limpiar los event listeners manuales”Siempre limpiar los event listeners manuales para evitar memory leaks. Ejemplo en el video
6. No usar TypeScript
Section titled “6. No usar TypeScript”7. Aplicar destructuring en datos reactivos
Section titled “7. Aplicar destructuring en datos reactivos”En el siguiente ejemplo, estamos aplicando destructuring en un objeto reactivo. El problema es que estamos destruyendo la reactividad del objeto.
<script setup lang="ts">import { reactive, toRefs } from "vue";const animal = reactive({ name: "Lion", diet: "Carnivore", lifespan: "8-12 years",});
const { name, diet, lifespan } = animal;</script><template> <ul> <li>Name: {{ name }}</li> <li>Diet: {{ diet }}</li> <li>Lifespan: {{ lifespan }}</li> </ul></template>Para solucionar este problema, usamos toRefs. toRefs convierte un objeto reactivo en un objeto de referencias reactivas.
<script setup lang="ts">import { reactive, toRefs } from "vue";const animal = reactive({ name: "Lion", diet: "Carnivore", lifespan: "8-12 years",});
const { name, diet, lifespan } = toRefs(animal);</script><template> <ul> <li>Name: {{ name }}</li> <li>Diet: {{ diet }}</li> <li>Lifespan: {{ lifespan }}</li> </ul></template>Veamos un ejemplo usando un composable.
import { reactive, toRefs } from "vue";export const useLion = () => { const animal = reactive({ name: "Lion", diet: "Carnivore", lifespan: "8-12 years", }); return toRefs(animal);};Como podemos ver, es tan sencillo como usar el toRefs en el return del objeto. De esta forma, podemos usar destructuring en el componente sin perder la reactividad.
<script setup>import { reactive, toRefs } from "vue";import { useLion } from "@/composables/useLion";const { diet, lifespan, name } = useLion();</script><template> <ul> <li>Name: {{ name }}</li> <li>Diet: {{ diet }}</li> <li>Lifespan: {{ lifespan }}</li> </ul></template>8. Inyectar html en la directiva v-html
Section titled “8. Inyectar html en la directiva v-html”La directiva v-html es una directiva de Vue que permite inyectar html en un elemento. Sin embargo, es importante tener en cuenta que esta directiva no es segura y puede llevar a ataques XSS.
Para evitar esto, es importante usar la directiva v-html con precaución y nunca inyectar html de usuarios no confiables.
Otro paso a seguir para añadir seguridad, es utilizar la libreria DOMPurify que nos ayudará a limpiar el html inyectado.
Ejemplo de uso de DOMPurify
<p v-html="DOMPurify.sanitize(myCodeHTML)"></p>