VUE Flashcards

1
Q

patrón Presentational/Container

A

El patrón Container/Presentational separa componentes en dos tipos:

Contenedor:
- Maneja lógica y estado
- Realiza llamadas API
- Procesa datos
- No tiene estilos propios
- Pasa datos via props

Presentacional:
- Renderiza UI
- Recibe datos via props
- Sin lógica compleja
- Emite eventos
- Reutilizable

Ejemplo:

```vue
// UserContainer.vue

<template>
<UserList
:users="users"
@user-select="handleSelect"
/>
</template>

<script>
export default {
  data() {
    return { users: [] }
  },
  created() {
    this.fetchUsers()
  },
  methods: {
    async fetchUsers() {
      this.users = await api.getUsers()
    }
  }
}
</script>

// UserList.vue (Presentacional)

<template>
<ul>
<li v-for="user in users" @click="$emit('user-select', user)">
{{ user.name }}
</li>
</ul>
</template>

~~~

Beneficios:
- Mejor mantenibilidad
- Componentes reutilizables
- Testing más sencillo
- Separación de responsabilidades

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Reactividad en VUE 2

A

Funcionamiento de la reactividad en Vue 2

Conceptos básicos:
1. Sistema reactivo:
- Los datos en el objeto data son observados.
- Cuando un valor cambia, Vue actualiza automáticamente la interfaz de usuario.

  1. Mecanismos internos:
    • Object.defineProperty: Convierte las propiedades de data en “getter” y “setter” para detectar cambios.
    • Dependencias: Rastrea qué componentes usan qué propiedades y actualiza solo los componentes afectados cuando una propiedad cambia.

Limitaciones:
- Propiedades dinámicas:
- Las propiedades añadidas después de la inicialización no son reactivas, a menos que uses Vue.set() o this.$set().
- Arrays:
- No detecta cambios en índices modificados directamente (arr[index] = value).
- Detecta cambios si se usan métodos como push, pop, shift, o unshift.

Mejora de rendimiento:
1. Usa Vue.set() o this.$set() para agregar propiedades reactivas.
2. Usa v-once para renderizar contenido estático solo una vez.

Resumen:
Este sistema permite que Vue 2 sea eficiente en la actualización de interfaces.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Vue.set() y this.$set() en Vue 2:

A

Vue.set() y this.$set() en Vue 2:
En Vue 2, cuando se agregan nuevas propiedades a un objeto después de la inicialización, esas propiedades no son reactivas por defecto. Para hacerlas reactivas, se debe usar Vue.set() o this.$set(), lo que permite a Vue observar las nuevas propiedades y actualizar la vista si cambian.

  • Vue.set(obj, key, value): Usado para agregar una propiedad reactiva a un objeto.
  • this.$set(obj, key, value): Es la versión de instancia del mismo método, usado dentro de los métodos de los componentes.

Ejemplo de uso:

```javascript
data: {
user: { name: ‘John’ }
},
methods: {
addAge() {
// Usando Vue.set para hacer que la propiedad ‘age’ sea reactiva
Vue.set(this.user, ‘age’, 30);
}
}
~~~

Al usar Vue.set(), si modificas user.age, Vue podrá reaccionar y actualizar la vista correctamente. Sin Vue.set(), age no sería reactivo.

Resumen:
- Object.defineProperty: Usado internamente por Vue para hacer que las propiedades de data sean reactivas.
- Vue.set() o this.$set(): Métodos para agregar propiedades reactivas a objetos después de su creación.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Object.defineProperty en Vue 2

A

Object.defineProperty en Vue 2:
Vue 2 usa Object.defineProperty para hacer que las propiedades del objeto data sean reactivas. Al convertir las propiedades en “getters” y “setters”, Vue puede interceptar el acceso y las modificaciones a los datos, lo que le permite actualizar la vista automáticamente cuando los datos cambian.

  • Getter: Cuando se accede a la propiedad, Vue registra la dependencia (el componente que la usa).
  • Setter: Cuando se modifica la propiedad, Vue sabe que debe actualizar la vista.

Ejemplo:

```javascript
const data = { message: ‘Hello’ };
Object.defineProperty(data, ‘message’, {
get() {
// Cuando se accede, Vue registra la dependencia
return this._message;
},
set(value) {
// Cuando se modifica, Vue actualiza la vista
this._message = value;
console.log(‘Message changed:’, value);
}
});

data.message = ‘Hello, Vue!’;
console.log(data.message); // “Hello, Vue!”
~~~

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Limitaciones con arrays y objetos

A

En Vue 2, hay algunas limitaciones con respecto a cómo maneja la reactividad de arrays y objetos. Aunque Vue 2 es muy eficiente en detectar cambios, tiene dificultades con ciertos tipos de modificaciones, especialmente en arrays y objetos. A continuación, te explico estas limitaciones y cómo manejarlas:

Limitaciones con Arrays:

  1. Modificación directa de índices:
    Vue 2 no puede detectar cambios cuando se modifican los elementos de un array directamente por índice. Por ejemplo:
    javascript
    this.myArray[2] = 'new value';  // Vue no detecta este cambio
    Para solucionar esto, Vue recomienda usar métodos mutativos del array que son reactivamente observados, como:
    - push()
    - pop()
    - shift()
    - unshift()
    - splice()Ejemplo:
    javascript
    this.myArray.splice(2, 1, 'new value');  // Vue detecta el cambio
  2. Agregar nuevos elementos al array:
    Si agregas nuevos elementos fuera de los índices actuales del array, Vue 2 detecta los cambios. Sin embargo, si estás agregando elementos a una posición específica, y no al final o al principio, se recomienda usar Vue.set() o this.$set() para garantizar la reactividad.Ejemplo con Vue.set() o this.$set():
    javascript
    this.$set(this.myArray, 5, 'new value');  // Agrega un elemento en el índice 5

Limitaciones con Objetos:

  1. Agregar nuevas propiedades:
    Vue 2 no puede detectar nuevas propiedades que se agregan a un objeto después de su inicialización. Por ejemplo, si agregas una nueva propiedad a un objeto sin usar Vue.set() o this.$set(), Vue no podrá hacer que esa propiedad sea reactiva.Ejemplo sin Vue.set():
    javascript
    this.user.age = 30;  // Vue no detecta este cambio
    Solución con Vue.set() o this.$set():
    javascript
    this.$set(this.user, 'age', 30);  // Vue detecta el cambio
  2. Eliminar propiedades:
    Cuando eliminas propiedades de un objeto con delete, Vue no puede detectar la eliminación de forma reactiva. Si necesitas que Vue actualice la vista después de eliminar una propiedad, puedes usar Vue.delete() o this.$delete().Ejemplo con Vue.delete():
    javascript
    this.$delete(this.user, 'age');  // Elimina 'age' de user y Vue actualiza la vista

Resumen de las Limitaciones y Soluciones:

  • Arrays: Vue 2 no detecta cambios al modificar directamente los índices de un array. Usa métodos mutativos (push(), pop(), splice()) o Vue.set() para hacer cambios reactivos en los índices específicos.
  • Objetos: Cuando agregas o eliminas propiedades después de la inicialización, Vue no puede detectarlas. Usa Vue.set() o this.$set() para agregar propiedades reactivas, y Vue.delete() o this.$delete() para eliminarlas de manera reactiva.

Estas limitaciones se solucionan fácilmente utilizando las herramientas que Vue proporciona, y esto garantiza que los cambios sean observados y reflejados en la interfaz de usuario.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Como VUE registra cambios

A

Vue detecta cambios en los datos mediante un sistema de reactividad basado en getter y setter. El proceso implica un conjunto de pasos que permiten a Vue hacer un seguimiento de los datos y actualizar la interfaz de usuario (DOM) de manera eficiente cada vez que esos datos cambian. A continuación te explico cómo funciona:

  1. Transformación de Datos en Reactivos:
    Cuando Vue instancia un componente, toma el objeto data y convierte sus propiedades en reactivas utilizando Object.defineProperty(). Esto permite que Vue sepa cuándo se accede a o se modifica un valor.
  • Getter: Cuando Vue accede a una propiedad para renderizarla, se registra una “dependencia”. Esto significa que Vue sabe qué vistas (o componentes) dependen de esa propiedad.
  • Setter: Cuando se modifica una propiedad reactiva, Vue marca la vista como “sucia”, lo que significa que necesita ser actualizada.
  1. Sistema de Dependencias:
    - Registro de dependencias: Cuando un componente usa una propiedad de data (por ejemplo, {{ message }}), Vue registra esa propiedad como una dependencia de ese componente. Esto se realiza a través del getter de la propiedad.
    - Reactividad: Cuando el valor de esa propiedad cambia, Vue sabe qué componentes o vistas necesitan ser actualizados debido a las dependencias registradas. Esto asegura que solo se actualicen los componentes afectados, mejorando el rendimiento.
  2. ¿Qué ocurre cuando los datos cambian?
    Cuando se cambia el valor de una propiedad reactiva:
    - El setter se ejecuta, lo que marca la propiedad como “sucia”.
    - Vue re-renderiza las partes de la vista que dependen de esa propiedad (esto es eficiente gracias al sistema de dependencias).
  3. Cómo Vue Actualiza el DOM:
    - Cuando una propiedad reactiva cambia, Vue pasa a una fase llamada “digest” (proceso de verificación), en la que Vue compara el estado actual de las propiedades con los estados anteriores. Si algo ha cambiado, Vue actualiza el DOM de manera eficiente.
    - Patch: Vue realiza un “parche” en el DOM, actualizando solo los nodos que necesitan ser cambiados, en lugar de volver a renderizar toda la vista.
  4. Limitaciones de la Detección de Cambios:
    Aunque Vue tiene un sistema eficiente para detectar cambios, hay algunas limitaciones:
    - Propiedades agregadas dinámicamente: Si se agrega una propiedad a un objeto después de su creación (por ejemplo, this.user.age = 30), Vue no puede detectar este cambio de manera reactiva a menos que uses Vue.set() o this.$set().
    - Cambio de índice de arrays: Vue no detecta cambios cuando modificas un índice específico de un array directamente (por ejemplo, arr[2] = 'new value'). Para cambios detectables, debes usar métodos como splice() o push().
  5. Resumen del Proceso:
  6. Object.defineProperty(): Convierte las propiedades de data en “reactivas” (con getter y setter).
  7. Dependencias: Vue registra qué componentes dependen de qué propiedades.
  8. Reactividad: Cuando los datos cambian, Vue sabe qué actualizar y lo hace de forma eficiente.
  9. Ejemplo Básico:

```javascript
new Vue({
data: {
message: ‘Hello Vue!’
},
created() {
console.log(this.message); // Accede a ‘message’, Vue lo registra como una dependencia
}
});
~~~

En este ejemplo, cuando el valor de message cambia, Vue actualizará automáticamente el DOM en las vistas que dependen de esa propiedad.

Conclusión:
Vue utiliza un sistema de reactividad eficiente basado en getters y setters para detectar cambios y actualizar el DOM solo cuando es necesario. Esto asegura que las aplicaciones de Vue sean rápidas y eficientes.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Ciclo de vida de componentes en Vue:

A

Ciclo de vida de componentes en Vue:

  1. created: El componente ha sido creado, pero aún no se ha montado en el DOM. Se puede acceder al data y a las propiedades computadas. Ideal para inicializar datos o hacer peticiones de API. ACCEDE A TODO PERO NO PODES MODIFICAR EL DOM.
  2. mounted: El componente se ha montado en el DOM, lo que significa que el DOM ya está disponible. Es el lugar ideal para interactuar con elementos del DOM, como iniciar animaciones o bibliotecas de terceros.
  3. updated: Se ejecuta cada vez que el componente y su DOM son actualizados debido a un cambio en los datos reactivos. Aquí se puede reaccionar ante actualizaciones en el estado del componente.
  4. beforeDestroy: Se ejecuta justo antes de que el componente sea destruido. El DOM y el estado reactivo todavía están disponibles, por lo que es ideal para limpiar timers, listeners de eventos o recursos externos antes de que el componente sea eliminado.
  5. destroyed: El componente ha sido destruido y su DOM ha sido eliminado. Es el último paso en el ciclo de vida. Aquí se asegura que todo lo relacionado con el componente se haya eliminado.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

created

A
  1. created
    Uso: Este hook se llama justo después de que el componente ha sido instanciado, pero antes de que se monte en el DOM. Es útil cuando necesitas realizar acciones que no dependen del DOM, pero sí del estado del componente.Casos de uso:
    - Inicializar datos: Cargar datos desde una API o base de datos.
    - Configurar propiedades: Establecer valores iniciales en los datos reactivos.
    - Lógica de negocios previa al montaje: Ejecutar funciones que no requieran acceso al DOM.Ejemplo:
    javascript
    created() {
      this.fetchData();
    }
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

mounted

A
  1. mounted
    Uso: Este hook se llama cuando el componente ha sido montado en el DOM, lo que significa que se pueden realizar interacciones con el DOM. Ideal para tareas que requieren acceso al DOM o a bibliotecas externas.

CHARTJS

Casos de uso:
- Acceder al DOM: Realizar manipulaciones directas del DOM, como la inicialización de un slider o una biblioteca de gráficos.
- Eventos de terceros: Integrar con bibliotecas externas que requieren acceso al DOM, como jQuery o D3.js.
- Iniciar animaciones: Ejecutar animaciones que necesitan que el DOM ya esté presente.

Ejemplo:

javascript
   mounted() {
     this.$nextTick(() => {
       this.initializeSlider();
     });
   }
  
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

updated

A
  1. updated
    Uso: Este hook se ejecuta cada vez que el componente y su DOM son actualizados, es decir, cuando los datos reactivos del componente cambian. Es útil cuando necesitas realizar acciones basadas en cambios de datos o cuando el DOM necesita ser ajustado después de una actualización.Casos de uso:
    - Reacciones a cambios de datos: Actualizar o recalcular algo en el DOM cuando los datos cambian.
    - Sincronización con el DOM: Realizar ajustes adicionales en el DOM después de que se haya renderizado, como recalcular tamaños de elementos.
    - Lógica basada en el estado del componente: Ejecutar funciones solo cuando los datos del componente hayan cambiado.Ejemplo:
    javascript
    updated() {
      this.adjustLayout();
    }
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

destroyed

A
  1. destroyed
    Uso: Este hook se llama cuando el componente ha sido destruido y su DOM ha sido removido. Es el lugar adecuado para limpiar recursos y evitar fugas de memoria, como cancelar solicitudes de red o remover listeners de eventos.Casos de uso:
    - Limpiar recursos: Eliminar suscripciones, eventos o temporizadores.
    - Destruir objetos de terceros: Liberar recursos de bibliotecas de terceros o herramientas que se hayan integrado en el componente.
    - Cancelar peticiones de red: Detener cualquier solicitud de API pendiente.Ejemplo:
    javascript
    destroyed() {
      clearInterval(this.timer);
      this.removeEventListeners();
    }

Resumen:

  • created: Ideal para inicializar datos, realizar peticiones y configurar el estado antes de que el componente se monte.
  • mounted: Perfecto para trabajar con el DOM, bibliotecas de terceros, o realizar tareas que dependan de que el componente ya esté en la página.
  • updated: Usado para reaccionar a cambios en los datos reactivos, actualizar el DOM o realizar ajustes tras una actualización.
  • destroyed: Usado para limpiar recursos, cancelar suscripciones y evitar fugas de memoria cuando el componente se destruye.

Cada uno de estos hooks ofrece un momento específico en el ciclo de vida del componente para realizar tareas de manera eficiente y efectiva.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Manejo de limpieza de recursos

A

El manejo de limpieza de recursos es crucial en aplicaciones Vue para evitar fugas de memoria y garantizar un rendimiento eficiente. Esto es especialmente importante cuando trabajas con recursos externos como suscripciones a eventos, temporizadores, peticiones de red o bibliotecas de terceros que necesitan ser detenidas o limpiadas cuando un componente se destruye.

¿Por qué es importante limpiar recursos?
Cuando los componentes se destruyen y no se limpian adecuadamente sus recursos (como listeners de eventos, intervalos de tiempo, conexiones de red, etc.), estos recursos permanecen en memoria, lo que puede causar fugas de memoria y afectar el rendimiento de la aplicación.

Casos Comunes para Limpiar Recursos:

  1. Event Listeners (Escuchadores de eventos):
    Si un componente escucha eventos globales o eventos en el DOM, debes asegurarte de eliminar estos listeners cuando el componente se destruya.Ejemplo:
    javascript
    mounted() {
      // Agregar un listener de evento global
      window.addEventListener('resize', this.handleResize);
    },
    destroyed() {
      // Limpiar el listener cuando el componente se destruya
      window.removeEventListener('resize', this.handleResize);
    },
    methods: {
      handleResize() {
        console.log('Window resized!');
      }
    }
  2. Timers (Temporizadores):
    Si usas setInterval o setTimeout en tu componente, debes limpiarlos cuando el componente se destruya para evitar que continúen ejecutándose innecesariamente.Ejemplo:
    javascript
    mounted() {
      // Iniciar un temporizador
      this.timer = setInterval(() => {
        console.log('Tick!');
      }, 1000);
    },
    destroyed() {
      // Limpiar el temporizador
      clearInterval(this.timer);
    }
  3. Conexiones de red o peticiones API:
    Si realizas peticiones de red en tus componentes, es importante asegurarse de que no haya solicitudes pendientes cuando el componente se destruye, especialmente si estas peticiones están actualizando el estado del componente.Ejemplo:
    ```javascript
    data() {
    return {
    apiData: null
    };
    },
    mounted() {
    this.fetchData();
    },
    destroyed() {
    // Cancelar cualquier solicitud de red si es necesario
    if (this.cancelRequest) {
    this.cancelRequest();
    }
    },
    methods: {
    fetchData() {
    // Imagina que esta función retorna un objeto que tiene un método ‘cancel’
    const cancelToken = axios.CancelToken.source();
    this.cancelRequest = cancelToken.cancel;
    axios.get('/api/data', { cancelToken: cancelToken.token })
      .then(response => {
        this.apiData = response.data;
      })
      .catch(error => {
        if (axios.isCancel(error)) {
          console.log('Request cancelled');
        }
      });   } } ```
  4. Bibliotecas de terceros:
    Algunas bibliotecas de terceros pueden requerir limpieza o destrucción manual de recursos, como la eliminación de elementos del DOM, la detención de animaciones o la destrucción de instancias.Ejemplo:
    javascript
    mounted() {
      // Inicializar una biblioteca de terceros
      this.slider = new SomeSliderLibrary('#slider');
      this.slider.init();
    },
    destroyed() {
      // Limpiar la biblioteca externa
      if (this.slider) {
        this.slider.destroy();
      }
    }

Métodos de Vue para Manejo de Recursos:

  • destroyed / beforeDestroy: Estos hooks son ideales para la limpieza de recursos. beforeDestroy se ejecuta antes de que Vue destruya el componente, mientras que destroyed se ejecuta después. En general, usa destroyed para la mayoría de las tareas de limpieza, ya que en beforeDestroy aún no se ha removido el DOM asociado al componente.
  • beforeDestroy: Si necesitas limpiar recursos antes de que el componente se destruya (por ejemplo, detener animaciones antes de que desaparezca el DOM), usa este hook.

Ejemplo Completo de Limpieza de Recursos:

```javascript

<template>
<div>
<button @click="toggleTimer">Start/Stop Timer</button>
</div>
</template>

<script>
export default {
  data() {
    return {
      timer: null,
      intervalId: null
    };
  },
  mounted() {
    console.log('Component mounted!');
    // Inicializar cualquier recurso (ej. temporizador)
  },
  methods: {
    toggleTimer() {
      if (this.intervalId) {
        // Detener el temporizador
        clearInterval(this.intervalId);
        this.intervalId = null;
      } else {
        // Iniciar un nuevo temporizador
        this.intervalId = setInterval(() => {
          console.log('Timer is running');
        }, 1000);
      }
    }
  },
  destroyed() {
    // Limpiar cualquier recurso cuando el componente se destruya
    if (this.intervalId) {
      clearInterval(this.intervalId);
    }
    console.log('Component destroyed!');
  }
};
</script>

~~~

Resumen:
1. Escuchadores de eventos: Usa addEventListener y removeEventListener.
2. Temporizadores: Usa setInterval y clearInterval.
3. Peticiones de red: Asegúrate de cancelar peticiones pendientes usando cancelToken de Axios o manejadores similares.
4. Bibliotecas de terceros: Llama a los métodos de destrucción de las bibliotecas externas cuando ya no las necesites.

La limpieza de recursos es esencial para evitar fugas de memoria y mejorar el rendimiento de la aplicación, especialmente en aplicaciones grandes que manejan múltiples componentes y recursos.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

¿Cómo se aplica el principio de responsabilidad única (SRP) de SOLID en un proyecto de Vue 2?

A

Para aplicar el SRP en Vue 2:

  1. Dividir componentes:
    • Cada componente debe tener una única responsabilidad, por ejemplo:
      • Un componente para la interfaz de usuario (UI).
      • Otro para manejar lógica específica, como formularios o listas.
    • Evita que un solo componente maneje múltiples responsabilidades.
  2. Organización del código:
    • Mueve funciones reutilizables o específicas a módulos externos (como servicios o helpers).
    • Ejemplo: Crea un archivo apiService.js para manejar peticiones HTTP en lugar de hacerlo directamente en el componente.
  3. Separar preocupaciones:
    • Usa Mixins o Composition API (en Vue 3) para extraer lógica compartida.
    • Mantén la lógica del negocio fuera del componente. Implementa un patrón como el Controlador (Controller) para separar la vista de la lógica.
  4. Ejemplo práctico:
    • En lugar de manejar directamente la lógica de un formulario en un componente, crea un archivo externo para validaciones:
      javascript
      // validationService.js
      export function validateForm(data) {
        // Lógica de validación --------sadadasdad---
        return { valid: true, errors: [] };
      }

      En el componente:
      ```javascript
      import { validateForm } from ‘./validationService’;export default {
      methods: {
      handleSubmit() {
      const result = validateForm(this.formData);
      if (!result.valid) {
      this.errors = result.errors;
      }
      },
      },
      };
      ```

Este enfoque asegura que cada pieza del código tiene una responsabilidad clara, es más fácil de mantener y se adhiere al principio SRP de SOLID.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Open/Closed Principle vue2

A

Pregunta:
¿Cómo se aplica el principio de abierto/cerrado (Open/Closed Principle) de SOLID en un proyecto de Vue 2?

Respuesta:
Para aplicar el principio de abierto/cerrado (OCP) en Vue 2:

  1. Definición del OCP:
    • El código debe ser abierto para extensión pero cerrado para modificaciones. Esto significa que puedes agregar nueva funcionalidad sin cambiar el código existente.
  2. Usar componentes reutilizables:
    • Crea componentes genéricos que puedan ser extendidos.
    • Ejemplo: Un componente de Button que reciba props para personalizar el estilo y el comportamiento:
      ```javascript
      <template>
      <button :class="btnClass" @click="onClick">
      <slot></slot>
      </button>
      </template>
      <script>
      export default {
        props: {
          btnClass: { type: String, default: 'btn-primary' },
          onClick: { type: Function, default: () => {} },
        },
      };
      </script>
      ```
      Ahora, puedes extenderlo para crear botones específicos sin modificar el componente base.
  3. Usar estrategias o inyección de dependencias:
    • Implementa patrones como el Strategy para cambiar comportamientos sin modificar el código base.
    • Ejemplo: Un sistema de validación extensible:
      ```javascript
      // validators.js
      export const required = value => value ? null : ‘Campo requerido’;
      export const minLength = length => value =>
      value.length >= length ? null : Mínimo ${length} caracteres;// validatorService.js
      export function validate(value, rules) {
      return rules.map(rule => rule(value)).filter(error => error);
      }
      En el componente:  
      javascript
      import { validate } from ‘./validatorService’;
      import { required, minLength } from ‘./validators’;export default {
      data() {
      return { formData: ‘’, errors: [] };
      },
      methods: {
      validateForm() {
      this.errors = validate(this.formData, [required, minLength(3)]);
      },
      },
      };
      ```
  4. Plugins o mixins:
    • Usa mixins o plugins para extender la funcionalidad de Vue de forma modular y sin modificar los componentes existentes.

Este enfoque respeta el OCP al permitir agregar funcionalidades sin alterar el código ya implementado, lo que mejora la mantenibilidad y escalabilidad.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

¿Cómo se implementa la inyección de dependencias en Vue 2?

A

En Vue 2, puedes implementar inyección de dependencias utilizando las propiedades provide y inject. Estas permiten compartir dependencias entre un componente padre y sus descendientes sin necesidad de pasarlas explícitamente a través de props.

Pasos para implementar la inyección de dependencias:

  1. Define las dependencias en el componente padre:
    • Usa la propiedad provide para especificar qué dependencias estarán disponibles para los descendientes.
    javascript
    export default {
      provide() {
        return {
          myService: this.myService,
        };
      },
      data() {
        return {
          myService: {
            getData: () => ['item1', 'item2', 'item3'],
          },
        };
      },
    };
  2. Consume las dependencias en componentes hijos:
    • Usa la propiedad inject para acceder a las dependencias proporcionadas por el padre.
    javascript
    export default {
      inject: ['myService'],
      mounted() {
        console.log(this.myService.getData()); // ['item1', 'item2', 'item3']
      },
    };

Ventajas:
- Desacoplamiento: Los componentes hijos no necesitan conocer la implementación exacta del servicio o dependencia.
- Mantenibilidad: Cambiar la lógica de las dependencias en el padre no requiere modificaciones en los hijos.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

¿Cómo se aplica el principio de sustitución de Liskov (LSP) en un proyecto de Vue 2?

A

El principio de sustitución de Liskov (LSP), parte de los principios SOLID, establece que “si ( S ) es un subtipo de ( T ), entonces los objetos de tipo ( T ) pueden ser reemplazados por objetos de tipo ( S ) sin alterar el comportamiento correcto del programa”. Esto significa que las subclases deben ser completamente intercambiables con sus clases base sin introducir errores.

En un proyecto con Vue 2, el LSP puede aplicarse al diseñar componentes o servicios para garantizar que las extensiones o reemplazos de estos sean coherentes con las expectativas del programa principal.

Ejemplo práctico

Supongamos que tienes un componente base para mostrar tarjetas de usuario:

Componente base: UserCard
```vue

<template>
<div>
<h3>{{ user.name }}</h3>
<p>{{ user.email }}</p>
</div>
</template>

<script>
export default {
  props: {
    user: {
      type: Object,
      required: true,
    },
  },
};
</script>
Subcomponente: `AdminCard`
Ahora, creamos una subclase (componente) que extiende `UserCard`, agregando información adicional para administradores.

```vue
<template>
  <div class="user-card admin-card">
    <h3>{{ user.name }} (Admin)</h3>
    <p>{{ user.email }}</p>
    <p>{{ user.adminLevel }}</p>
  </div>
</template>

<script>
import UserCard from './UserCard.vue';

export default {
  extends: UserCard,
};
</script>

Aplicación del LSP
Ambos componentes (UserCard y AdminCard) deben ser intercambiables en cualquier contexto donde se espere una UserCard. Por ejemplo:

Usando un array de usuarios mixtos
```vue

<template>
<div>
<component
v-for="(user, index) in users"
:is="user.isAdmin ? 'AdminCard' : 'UserCard'"
:key="index"
:user="user"
/>
</div>
</template>

<script>
import UserCard from './UserCard.vue';
import AdminCard from './AdminCard.vue';

export default {
  components: {
    UserCard,
    AdminCard,
  },
  data() {
    return {
      users: [
        { name: 'Juan', email: 'juan@example.com', isAdmin: false },
        { name: 'Ana', email: 'ana@example.com', adminLevel: 'Super', isAdmin: true },
      ],
    };
  },
};
</script>

~~~

Cómo evitar violaciones al LSP
1. Mantén contratos claros: Define qué propiedades y comportamientos se esperan de las clases base. Por ejemplo, todos los objetos deben tener al menos name y email.

  1. Evita agregar requisitos adicionales: Si AdminCard requiere algo extra (por ejemplo, adminLevel) pero no puede manejar la falta de ese dato, rompe el LSP.
  2. Prueba sustituciones: Asegúrate de que cualquier subcomponente (como AdminCard) pueda ser usado sin modificaciones en los contextos donde se usa el componente base (UserCard).

De esta forma, aplicas el principio de Liskov en el desarrollo de componentes en Vue 2, garantizando que tu código sea flexible y extensible sin perder robustez.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

interface surrogation

A

Respuesta:
El Principio de Segregación de Interfaces (ISP) establece que los clientes no deben depender de interfaces que no utilizan. En otras palabras, es mejor tener varias interfaces específicas que una interfaz genérica grande. En Vue 2 con TypeScript, puedes aplicarlo así:

  1. Evita interfaces genéricas innecesarias:
    Si defines una interfaz que agrupa muchas responsabilidades, los clientes que no usen todas esas funcionalidades estarán sobrecargados.
    Ejemplo de mala práctica:
    typescript
    interface UserService {
      getUser(): string;
      updateUser(name: string): void;
      deleteUser(): void;
    }
  2. Divide interfaces grandes en interfaces específicas:
    Crea interfaces más pequeñas basadas en las responsabilidades reales de los clientes.
    Ejemplo de buena práctica:
    ```typescript
    interface UserReader {
    getUser(): string;
    }interface UserWriter {
    updateUser(name: string): void;
    }interface UserDeleter {
    deleteUser(): void;
    }
    ```
  3. Implementa clases que cumplan interfaces específicas:
    Cada clase debe implementar solo las interfaces necesarias para su funcionalidad.
    ```typescript
    class AdminService implements UserReader, UserWriter, UserDeleter {
    getUser(): string {
    return “Admin User”;
    }
    updateUser(name: string): void {
    console.log(Admin updated to ${name});
    }
    deleteUser(): void {
    console.log(“Admin deleted”);
    }
    }class ViewerService implements UserReader {
    getUser(): string {
    return “Viewer User”;
    }
    }
    ```
  4. Usa las interfaces específicas en tus componentes Vue:
    Los componentes deben depender solo de las interfaces que realmente necesitan.
    typescript
    export default Vue.extend({
      data() {
        return {
          userService: {} as UserReader, // Solo lectura
        };
      },
      methods: {
        showUser() {
          console.log(this.userService.getUser());
        },
      },
      created() {
        this.userService = new ViewerService(); // No depende de métodos innecesarios
      },
    });
  5. Cumple ISP:
    • Define interfaces específicas para cada caso de uso.
    • Asegúrate de que las clases no implementen métodos innecesarios.

Nota:
Romper ISP ocurre cuando un cliente necesita implementar métodos que no utiliza, creando dependencias innecesarias y dificultando la escalabilidad. Evítalo separando responsabilidades de manera lógica.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

Inversion de Dependencias

A

Para aplicar el principio de inversión de dependencias (DIP) en un proyecto con Vue 2 y TypeScript:

  1. Definir interfaces para abstraer dependencias:
    Declara una interfaz que defina los métodos y propiedades necesarias. Esto permite que el código dependa de una abstracción, no de una implementación concreta.
    ```typescript
    // services/LoggerService.ts
    export interface ILoggerService {
    log(message: string): void;
    }export class ConsoleLoggerService implements ILoggerService {
    log(message: string): void {
    console.log(message);
    }
    }
    ```
  2. Inyectar dependencias a través de provide/inject:
    Usa el mecanismo de provide y inject de Vue para desacoplar componentes de implementaciones específicas.
    ```typescript
    // main.ts
    import Vue from “vue”;
    import { ConsoleLoggerService, ILoggerService } from “./services/LoggerService”;const loggerService: ILoggerService = new ConsoleLoggerService();new Vue({
    provide: {
    loggerService,
    },
    render: (h) => h(App),
    }).$mount(“#app”);
    ```
  3. Usar la dependencia en los componentes:
    Inyecta la abstracción en los componentes que la necesiten, evitando acoplarte a una implementación concreta.
    ```typescript
    // components/MyComponent.vue

    import { defineComponent, inject } from "vue-property-decorator";
    import { ILoggerService } from "@/services/LoggerService";
    export default defineComponent({
    name: “MyComponent”,
    setup() {
    const loggerService = inject<ILoggerService>("loggerService");
    if (!loggerService) {
    throw new Error("LoggerService not provided!");
    }</ILoggerService>
        const logMessage = () => {
            loggerService.log("Hello, Dependency Inversion Principle!");
        };
    
        return { logMessage };
    }, }); </script>
    <template>
    <button @click="logMessage">Log Message</button>
    </template>```
  4. Cambiar implementaciones fácilmente:
    Si necesitas cambiar la implementación del servicio (por ejemplo, un logger que envíe datos a un servidor), solo necesitas reemplazar la clase proporcionada sin cambiar el código del componente.
    typescript
    // services/RemoteLoggerService.ts
    export class RemoteLoggerService implements ILoggerService {
        log(message: string): void {
            // Envía el mensaje a un servidor
            fetch("/api/logs", { method: "POST", body: JSON.stringify({ message }) });
        }
    }

Conclusión:
El DIP se implementa al depender de interfaces o abstracciones (en este caso, la interfaz ILoggerService), y al usar provide/inject para desacoplar componentes de las implementaciones específicas. Esto facilita el mantenimiento y escalabilidad de tu proyecto.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Event Bus

A

El Event Bus en Vue 2 es una forma de comunicación entre componentes que no están relacionados directamente (como padre-hijo). Se crea utilizando una instancia de Vue para emitir y escuchar eventos globalmente. Es útil para manejar datos o interacciones entre componentes de manera simple.

Por ejemplo:

  1. Emisor: Un componente puede enviar un evento con EventBus.$emit('evento', datos).
  2. Receptor: Otro componente escucha ese evento con EventBus.$on('evento', callback) y actúa en consecuencia.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

¿Cuáles son las ventajas de usar Vuex?

A

Centralización: Todo el estado compartido está en un único lugar (store).
Reactividad: Los cambios en el store actualizan automáticamente los componentes que dependen de esos datos.
Herramientas integradas: Soporte para depuración con Vue Devtools.
Escalabilidad: Ideal para proyectos grandes con datos complejos.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

¿Qué es Vuex?

A

Vuex es la librería oficial de gestión de estado para aplicaciones Vue. Proporciona un patrón centralizado para manejar datos compartidos y facilita la comunicación entre componentes en proyectos Vue 2.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

¿Cuáles son las desventajas de Vuex?

A

Complejidad: Requiere configuración adicional y más código (mutations, actions).
Verborrea: Necesita boilerplate para tareas simples.
**Curva de aprendizaje: **Puede ser abrumador para principiantes o proyectos pequeños.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

¿Cuáles son las alternativas a Vuex en Vue 2?

A

Back
1. Event Bus:
Comunicación directa entre componentes usando $emit y $on.
- Simplicidad para aplicaciones pequeñas.
- Difícil de mantener en proyectos grandes.

  1. Props y $emit:
    Ideal para comunicar datos entre componentes padre e hijo.
    • Fácil y directo para jerarquías simples.
    • Ineficiente para compartir datos globales.
  2. Plugins personalizados:
    Crear un objeto global con Vue.observable o Vue.prototype.
    • Flexibilidad para datos globales pequeños.
    • Sin herramientas de depuración como Vuex.
  3. Pinia (experimental en Vue 2):
    Librería más ligera y moderna, diseñada para Vue 3, pero compatible con Vue 2.
    • Menos boilerplate que Vuex.
    • Aún inmadura para Vue 2.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

¿Cuándo usar Vuex y cuándo un estado alternativo?

A
  • Usa Vuex si:
    Tu proyecto tiene múltiples componentes que comparten datos complejos o necesitas un patrón estructurado.
  • Usa un estado alternativo si:
    Tu aplicación es pequeña o mediana, y no necesitas la complejidad añadida de Vuex.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

¿Qué son las propiedades computadas (computed) en Vue?

A

Las propiedades computadas son funciones reactivas que dependen de datos del estado y se vuelven a calcular automáticamente cuando esos datos cambian. Su resultado se almacena en caché hasta que sus dependencias cambian.

26
Q

¿Qué son los watchers en Vue?

A

Los watchers son funciones reactivas que observan cambios en una propiedad o expresión y ejecutan código en respuesta a esos cambios.

27
Q

¿Cuáles son las ventajas de computed?

A

Solo se recalculan cuando cambian sus dependencias.
Simplifican la lógica: Ideales para transformaciones o cálculos basados en datos reactivos.
Legibilidad: mantienen el código limpio.

28
Q

¿Cuáles son las ventajas de watchers?

A

Flexibilidad: Permiten ejecutar cualquier acción en respuesta a cambios, no solo retornar valores.
Control total: Ideales para operaciones asíncronas o efectos secundarios.
Observación específica: Pueden reaccionar a cambios profundos o de valores complejos como objetos anidados.

29
Q

¿Cuándo usar computed en lugar de watchers?

A

Usa computed cuando:
* Necesites transformar o calcular valores que dependen de datos reactivos.
* El resultado sea necesario para la interfaz de usuario y pueda ser almacenado en caché.
* Quieras mantener el código más declarativo y limpio.

30
Q

¿Cuándo usar watchers en lugar de computed?

A
    1. Necesites ejecutar funciones o efectos secundarios en respuesta a un cambio de datos.
    1. Trabajes con operaciones asíncronas, como API calls.
    1. Requieras manejar cambios profundos en objetos complejos usando deep: true.
31
Q

¿Cuál es la principal diferencia entre computed y watchers?

A
    1. Computed: Devuelve un valor derivado, almacenado en caché, y pensado para la interfaz.
    1. Watchers: Ejecutan código en respuesta a cambios, ideales para efectos secundarios.
32
Q

¿Cuáles son los casos de uso ideales para computed?

A
  • Cálculos derivados de datos:
    Por ejemplo, mostrar el nombre completo a partir de firstName y lastName.
  • Formateo de datos para la UI:
    Como convertir una fecha en un formato legible.
  • Filtrar o mapear listas:
    Generar una lista filtrada basada en una propiedad reactiva.
33
Q

¿Cuáles son los casos de uso ideales para watchers?

A

Ejecución de operaciones asíncronas:
Hacer una llamada a una API cuando cambie un dato.
Efectos secundarios personalizados:
Por ejemplo, guardar automáticamente en localStorage cuando cambie un valor.
Seguimiento de cambios profundos:
Observar objetos anidados o arrays usando deep: true.
Sincronización manual:
Detectar cambios en un campo y actualizar otra propiedad o componente.

34
Q

¿Cómo manejan la optimización las propiedades computed?

A

1. Cacheado automático:
* El valor solo se recalcula si cambian sus dependencias.
* Esto evita cálculos innecesarios, mejorando el rendimiento.

2. Reactividad integrada:
* Perfectas para operaciones intensivas (como filtros en listas) porque minimizan las recomputaciones.

3. Uso en plantillas:
* Mejor que invocar métodos directamente, ya que no se ejecutan repetidamente durante el render.

35
Q

¿Cómo manejar la optimización con watchers?

A

Evitar watchers innecesarios:
Úsalos solo para casos específicos donde no se pueda usar computed.

Desactivar observaciones profundas si no son necesarias:
Configura deep: false para evitar sobrecarga en objetos grandes.

36
Q

¿Qué papel juega el cacheado en computed vs watchers?

A

Computed:
* Cacheado automático. Solo recalcula cuando cambian las dependencias. Esto es ideal para operaciones que retornan valores.
* Mejora el rendimiento en plantillas y componentes que dependen del mismo dato.

Watchers:
* No usan caché. Se ejecutan cada vez que el dato observado cambia, sin importar si el resultado de la operación es el mismo.
* Útil para efectos secundarios y procesos que no requieren almacenamiento en caché.

37
Q

¿Cuáles son los conceptos clave de Vuex?

A

State (Estado):
Donde se almacena la información global de la aplicación.
Getters:
Son funciones que permiten acceder al estado de forma derivada o calculada.
Mutations:
Métodos síncronos que modifican directamente el estado.
Actions:
Métodos asíncronos que pueden realizar operaciones y luego llamar a mutations.
Modules:
Dividen el store en partes más pequeñas para manejar estados más complejos.

38
Q

¿Cómo acceder al estado con Vuex en un componente?

A

1 - this.$store.state.count;
Ideal para:
* Prototipos o casos simples donde solo necesitas leer datos esporádicos.
* Situaciones donde no necesitas mapear múltiples propiedades del estado.

2 - import { mapState } from “vuex”;

export default {
computed: {
…mapState([“count”]),
},
};

  • Reactivo automáticamente: Las propiedades del estado mapeadas a computed reaccionan a los cambios en tiempo real.
  • Ideal para:
  • Componentes donde necesitas mapear varias propiedades del estado.
  • Mantenimiento más limpio y legible, especialmente en aplicaciones medianas o grandes.
39
Q

¿Cómo modificar el estado con Vuex?

A

En Vue.js, cuando trabajas con Vuex (el sistema de gestión de estado de Vue), se utilizan los métodos dispatch y commit para modificar el estado de la aplicación. La diferencia principal radica en cómo y dónde se usan:

1. commit
- Propósito: Se usa para llamar directamente a una mutación, que es la única forma permitida de modificar el estado en Vuex.
- Características:
- Es sincrónico, lo que significa que los cambios al estado ocurren inmediatamente.
- Solo puede invocar mutaciones definidas en el store.

  • Ejemplo:
    ```javascript
    // En el store
    mutations: {
    increment(state) {
    state.counter++;
    }
    }// En el componente
    this.$store.commit(‘increment’);
    ```

2. dispatch
- Propósito: Se usa para llamar a una acción, que puede contener lógica asincrónica (como llamadas a una API) y luego, dentro de esa acción, se puede llamar a una mutación para modificar el estado.
- Características:
- Es asincrónico, aunque también puede manejar operaciones sincrónicas.
- Las acciones pueden incluir lógica adicional como validaciones, transformación de datos, etc.
- Puede invocar otras acciones o mutaciones.

  • Ejemplo:
    ```javascript
    // En el store
    actions: {
    async fetchUserData({ commit }) {
    const data = await fetch(‘/api/user’);
    const user = await data.json();
    commit(‘setUser’, user);
    }
    }mutations: {
    setUser(state, user) {
    state.user = user;
    }
    }// En el componente
    this.$store.dispatch(‘fetchUserData’);
    ```

Cuando tengas una lógica más compleja o asincrónica, utiliza dispatch. Para cambios inmediatos y simples en el estado, utiliza commit.

40
Q

¿Cómo realizar operaciones asíncronas con Vuex?

A

Definir acciones en el store:

actions: {
  asyncIncrement({ commit }) {
    setTimeout(() => {
      commit("increment");
    }, 1000);
  },
},

Ejecutar una acción desde el componente:

this.$store.dispatch("asyncIncrement");
Mapeo con mapActions:
~~~
import { mapActions } from “vuex”;

export default {
methods: {
…mapActions([“asyncIncrement”]),
},
};
~~~

41
Q

¿Qué son los módulos en Vuex y para qué sirven?

A

Los módulos dividen el store en partes más pequeñas, cada una con su propio state, mutations, actions y getters.

42
Q

¿Cuáles son las mejores prácticas con Vuex?

A

Mantén el store simple: Usa solo lo necesario para la gestión global.
Divide el estado: Usa módulos para estados complejos.
Usa getters: Accede al estado de forma derivada.
Evita lógica compleja en mutations: Realiza esa lógica en actions o getters.
Nombrado consistente: Usa prefijos para módulos (user/login, cart/addItem).

43
Q

¿Qué son las mixins en Vue?

A

Las mixins en Vue son objetos que contienen opciones de componentes (como data, methods, created, etc.) que pueden ser compartidas entre varios componentes. Permiten reutilizar la lógica de manera eficiente.

44
Q

¿Cuándo usar las mixins en Vue?

A

Usa mixins cuando necesites compartir lógica entre varios componentes, como:

  • Reutilización de lógica común (validación de formularios, manejo de autenticación, etc.).
  • Reutilización de hooks del ciclo de vida (como created, mounted).
  • Comportamientos similares en múltiples componentes, con pequeñas diferencias.
45
Q

Ventajas de usar mixins

A
  • Reutilización de código: Centraliza la lógica compartida.
  • Reducción de duplicación: Evita repetir el mismo código en varios componentes.
  • Simplicidad: Útil para casos sencillos y de pequeña escala.
46
Q

¿Cómo manejar la comunicación entre componentes no directamente relacionados en Vue 2?

A
  • Event Bus (Bus de eventos):
    Un Event Bus es un componente centralizado que actúa como un canal de comunicación entre componentes. Los componentes pueden emitir eventos y escuchar eventos a través de este bus.
  • Vuex:
    Usar Vuex para gestionar el estado global y permitir que los componentes se comuniquen mediante el acceso y la mutación de este estado compartido.
  • Props y Eventos personalizados (con un componente intermedio):
    Si no deseas usar un bus de eventos, puedes usar un componente intermedio que reciba datos mediante props y los pase a otros componentes mediante eventos personalizados.
47
Q

¿Cómo implementar un sistema de caché para llamadas API en Vue 2?

A

Para implementar un sistema de caché en Vue 2 para llamadas a APIs, puedes usar una variable global (por ejemplo, en Vuex o en un objeto local) que almacene los resultados de las peticiones, y verificar si esos resultados ya están disponibles antes de hacer una nueva solicitud.

Usar Vuex para almacenar datos en caché (si es necesario que los datos sean accesibles en toda la aplicación)

Optimización: Verifica primero si los datos están en caché antes de hacer la solicitud, mejorando la eficiencia y reduciendo las llamadas repetidas a la API.

Uso de la acción en el componente:
~~~
export default {
computed: {
…mapState([‘cache’])
},
methods: {
…mapActions([‘fetchData’]),
loadData() {
this.fetchData(‘https://api.example.com/data’).then(data => {
console.log(data);
});
}
}
};
~~~

48
Q

¿Qué patrones de diseño usarías para manejar formularios complejos en Vue 2 con TypeScript?

A
    • Patrón de Validación de Formularios Centralizada: Mantén la validación del formulario separada de la lógica de presentación utilizando un store como Vuex para manejar el estado de validación.
    • Patrón de Componentes Compuestos: Divide el formulario en componentes más pequeños y reutilizables. Cada campo de formulario o grupo de campos puede ser un componente separado, facilitando la reutilización.
    • Formulario Reactivo: Usa la reactividad de Vue para mantener el estado del formulario sincronizado.
    • Validación Centralizada: Utiliza Vuex para manejar el estado de validación y errores.
    • Componentes Compuestos: Divide el formulario en componentes reutilizables y fáciles de mantener.
    • Manejo Global de Errores: Centraliza la lógica de manejo de errores para simplificar la gestión de validaciones.
49
Q

Patrón de Manejo de Errores Globales

A

Centraliza el manejo de errores utilizando un manejador global de errores para manejar los errores que puedan ocurrir en cualquier parte del formulario, en lugar de manejarlo por cada campo individualmente.

50
Q

¿Cómo optimizar el rendimiento de una aplicación Vue 2?

A

Usar Vue DevTools para detectar problemas:
Utiliza Vue DevTools para encontrar cuellos de botella en el rendimiento, como componentes innecesariamente renderizados.

Evitar renderizaciones innecesarias:
Usa el modificador v-once o v-memo para evitar la re-renderización de partes de la UI que no cambian.

Lazy Loading (Carga diferida) de componentes:
Implementa la carga diferida de componentes y rutas para cargar solo los módulos necesarios en el momento adecuado.

Optimización de listas con v-for y key:
Usa una clave única (key) en los elementos de listas renderizadas dinámicamente para mejorar el rendimiento de re-renderizado.

Debouncing y Throttling para eventos de entrada:
Aplica técnicas de debouncing o throttling en eventos como las entradas de usuario o el scroll para reducir el número de actualizaciones.

Usar v-show en lugar de v-if para elementos estáticos:
Usa v-show para elementos que no se van a ocultar y mostrar con frecuencia, ya que es más eficiente en términos de rendimiento.

51
Q

¿Qué es el “virtual DOM” y cómo optimiza el rendimiento de Vue?

A

Vue utiliza un virtual DOM para hacer un seguimiento de los cambios en la UI sin tener que manipular directamente el DOM real. Esto permite actualizaciones más rápidas, ya que Vue compara el estado actual del DOM con el anterior y realiza cambios solo cuando es necesario.

52
Q

¿Qué es el patrón Observer en el contexto de Vue?

A

El patrón Observer es un patrón de diseño en el que u**n objeto (el subject) mantiene una lista de sus dependientes (los observers) **y notifica a estos dependientes automáticamente cuando cambia su estado. En el contexto de Vue, Vue mismo actúa como un subject y los componentes o propiedades reactivas actúan como observers.

  • Vue implementa el patrón Observer utilizando su sistema de reactividad. Cuando un componente o propiedad observada cambia, Vue notifica a los componentes que dependen de esa propiedad, actualizando automáticamente la interfaz de usuario.
  • Data reactiva:
    Vue convierte las propiedades del objeto data en observables. Cada vez que una propiedad reactivada cambia, Vue notifica a todos los componentes que dependen de esa propiedad.
  • Dependencias reactivas:
    Vue rastrea las dependencias de las propiedades reactivas durante el renderizado de los componentes. Si una propiedad cambia, Vue actualiza solo los componentes que dependen de esa propiedad.
53
Q

¿Qué es el Virtual DOM y cómo funciona en Vue?

A

El Virtual DOM (VDOM) es una representación en memoria del DOM real. Vue utiliza un Virtual DOM para mejorar el rendimiento y eficiencia de la actualización de la interfaz de usuario (UI). En lugar de manipular directamente el DOM, Vue trabaja con el Virtual DOM, realiza las modificaciones y luego actualiza el DOM real de manera eficiente.

54
Q

¿Qué son las interfaces en TypeScript?

A

Las interfaces en TypeScript son una forma de definir un contrato en el que los objetos deben cumplir con una estructura específica. Las interfaces permiten que los objetos tengan propiedades y métodos con tipos específicos, lo que mejora la seguridad y la predictibilidad del código.

  • Definen la forma de un objeto.
  • Pueden ser implementadas por clases.
  • Pueden extenderse entre sí.
55
Q

¿Cómo manejarías la autenticación en una aplicación Vue?

A

Manejar la autenticación en una aplicación Vue implica la gestión de los estados de autenticación del usuario (inicio de sesión, cierre de sesión, verificación de token, etc.) y el manejo de rutas protegidas para evitar el acceso no autorizado.

Almacenar el token de autenticación:
* El token recibido de la API (generalmente un JWT) debe almacenarse de manera segura. Se puede almacenar en el localStorage o sessionStorage, pero el localStorage es más persistente.

Proteger las rutas:
* Usar Vue Router para proteger ciertas rutas y redirigir al usuario si no está autenticado.

Realizar peticiones autenticadas:
* Enviar el token en los encabezados de las peticiones API para autenticar al usuario.

  1. Almacenar el token de autenticación en localStorage.
  2. Usar Vue Router para proteger rutas con la propiedad meta.requiresAuth.
  3. Implementar el estado de autenticación con Vuex (opcional).
  4. Enviar el token en los encabezados de las peticiones API.
  5. Redirigir al usuario a la página de inicio de sesión si no está autenticado.
56
Q

¿Cuándo usar props en lugar de slots?

A

Usa props cuando necesites pasar datos desde un componente padre a un componente hijo de forma unidireccional.

  • Transferencia de datos: Para pasar información estática o dinámica del padre al hijo.
  • Controlar el estado: El componente padre es responsable del estado y pasa el estado necesario como props.
  • Comunicaciones simples: Cuando el componente hijo necesita acceder a un valor específico o realizar una acción en función de un valor recibido.
57
Q

¿Cuándo usar slots en lugar de props?

A

Usa slots cuando necesites proporcionar contenido en el componente hijo que puede variar según el componente padre, sin tener que definir explícitamente el contenido en el componente hijo.

Contenido dinámico: Cuando el contenido es proporcionado por el componente padre y puede variar en función de la situación.
Diseños flexibles: Permite la reutilización de componentes de manera flexible, ya que el contenido se inyecta en el hijo desde el padre.
Personalización de la UI: Cuando el componente hijo define una estructura pero el contenido específico puede ser decidido por el padre.

58
Q

¿Cómo manejarías el estado global sin Vuex?

A

Usar un Event Bus:
Es útil para aplicaciones pequeñas donde no se requiere una solución compleja. Un Event Bus es un objeto central que permite la comunicación entre componentes.

Propagar el estado a través de propiedades:
Pasar el estado a través de props y emisión de eventos entre los componentes, ideal para aplicaciones donde el estado no es tan grande o no cambia constantemente.

Instancia global de Vue:
Puedes usar una instancia global de Vue para almacenar datos compartidos entre componentes.

Almacenar el estado en localStorage o sessionStorage:
Almacenar el estado global en el almacenamiento local del navegador, útil para mantener el estado entre recargas de página.

59
Q

¿Qué es un Renderless Component?

A

Un Renderless Component es un patrón en Vue (y otros frameworks) donde el componente no renderiza nada por sí mismo. En lugar de eso, proporciona lógica y control a través de scoped slots o v-slot, dejando que el componente hijo o el consumidor se encargue de la renderización.

60
Q

¿Cuáles son las ventajas de usar un Renderless Component?

A
  • Reutilización de lógica: Permite compartir lógica entre diferentes componentes sin acoplar la presentación.
  • Flexibilidad: El consumidor decide cómo se renderiza el contenido, proporcionando un control total sobre la UI.
  • Separación de preocupaciones: Desacopla la lógica del componente de su presentación, mejorando la mantenibilidad.
61
Q

¿Qué es el Provider Pattern en Vue 2?

A

El Provider Pattern usando provide / inject es una técnica en Vue que permite pasar datos desde un componente ancestro a sus descendientes sin necesidad de pasar props explícitamente a través de cada nivel de la jerarquía de componentes. Esto es útil para compartir datos globales o configuraciones entre componentes sin propagar propiedades manualmente.

Los valores proporcionados a través de provide/inject no son automáticamente reactivos, a menos que sean referencias reactivas como ref o reactive

62
Q

¿Qué es un Closure en JavaScript?

A

Un closure es una función que “recuerda” el entorno en el que fue creada, incluso después de que la función externa haya terminado de ejecutarse. Es decir, un closure permite que una función interna acceda a las variables de su función externa, incluso si esa función externa ha finalizado su ejecución.