Reutilización de lógica y optimización del rendimiento

Después de completar el enrutamiento y la lógica de inicio de sesión, a medida que el proyecto crece, notaremos que cierta lógica (como almacenar/leer datos locales, mostrar notificaciones) aparece repetidamente en varias páginas. Además, si la lista de tareas llega a miles de elementos, la página puede volverse lenta.

En esta etapa, utilizaremosla aplicación avanzada de la Composition APIpara resolver los problemas de reutilización de código y los cuellos de botella de rendimiento.


Reutilización de lógica: Composables personalizados (Hooks)

Los Composables son la esencia de Vue 3; nos permiten extraer lógica (State + Actions) en funciones independientes.

useLocalStorage: Extracción de la lógica de persistencia de datos

Ya no escribimos manualmente en cada Store o componentelocalStorage.getItem。

Ejemplo

// src/composables/useLocalStorage.js
import { ref, watch } from 'vue';

export function useLocalStorage(key, defaultValue = null) {
  // 1. Inicializar datos
  const storedValue = localStorage.getItem(key);
  const data = ref(storedValue ? JSON.parse(storedValue) : defaultValue);

  // 2. Escuchar cambios y sincronizar automáticamente
  watch(data, (newValue) => {
    localStorage.setItem(key, JSON.stringify(newValue));
  }, { deep: true });

  return data;
}

useNotification: Extracción de lógica de UI común

Implementar una función simple de notificaciones.

Ejemplo

// src/composables/useNotification.js
import { ref } from 'vue';

export function useNotification() {
  const message = ref('');
  const isVisible = ref(false);

  const notify = (msg, duration = 2000) => {
    message.value = msg;
    isVisible.value = true;
    setTimeout(() => {
      isVisible.value = false;
    }, duration);
  };

  return { message, isVisible, notify };
}

Optimización del rendimiento: manejo de grandes volúmenes de datos y renderizado de alta frecuencia

Cuando tu TaskHub pasa de gestionar 10 tareas a gestionar 1000, la "reactividad profunda" predeterminada de Vue genera presión computacional.

shallowRefymarkRaw

Lo predeterminado de Vuerefes recursivamente reactivo (es decir, cada propiedad interna del objeto se convierte en un proxy).

shallowRef: Solo escuchar.valueel cambio de referencia, sin observar los cambios de las propiedades internas del objeto.

  • Escenario: cuando obtienes del backend una gran cantidad de registros de historial de tareas de solo lectura.

markRaw: marca un objeto para quenuncase convierta en reactivo.

  • Escenario: algunas instancias complejas de bibliotecas de terceros (como instancias de gráficos ECharts, instancias de mapas), al envolverlas en reactividad, pueden causar errores o consumir un rendimiento extremo.
// 性能优化示例
import { shallowRef, markRaw } from 'vue';

// 假设这是一万条历史归档数据
const archiveTasks = shallowRef([]); 

const loadArchive = (data) => {
  // 仅在赋值时触发一次响应式更新,内部属性修改不触发
  archiveTasks.value = data; 
};

v-onceyv-memo(Optimización a nivel de directivas)

v-once: contenido estático se renderiza solo una vez

Si una tarea no cambia después de renderizarse (por ejemplo, la hora de creación de la tarea), usav-once。

<span v-once>创建于: {{ task.createdAt }}</span>
  • Principio: después de renderizar, Vue omite la verificación de actualizaciones posteriores de ese nodo.

v-memo: actualización bajo demanda (Vue 3.2+)

Esta es la directiva más potente para optimizar listas largas. Acepta un array de dependencias y solo cuando cambian los valores del array, el nodo y sus hijos se vuelven a renderizar.

<li v-for="task in tasks" :key="task.id" v-memo="[task.isCompleted, task.title]">
  {{ task.title }} - {{ task.isCompleted }}
</li>

¿Cuándo se debe optimizar?

Solución Problema que resuelve Escenario recomendado
Composables Código duplicado, lógica dispersa Compartir lógica entre componentes (como verificación de inicio de sesión, cambio de tema)
shallowRef Sobrecarga de memoria causada por el proxy profundo de objetos grandes Cuando el volumen de datos de la lista > 1000 y solo se necesita reemplazar completa
v-memo Comparación frecuente del DOM virtual en listas largas Complejav-forlista, y solo unos pocos atributos cambian en cada elemento

Integración en el proyecto anterior

Puedes intentar aplicarTaskItem.vueen el proyecto.v-memo:

<template>
  <li v-memo="[task.id, task.isCompleted]" class="...">
     ...
  </li>
</template>

Ahora tu proyecto no solo tiene una lógica clara (Composables), sino también un rendimiento sólido.

Otras extensiones