vuejs

docs

  • [Introduction Vue.js](https://vuejs.org/guide/introduction.html)
  • Vue.js-introduction.html
  • DeepSeek-django-vs-vue

    conceptos

  • Templates
    • Sistema declarativo para estructurar la UI.
    • Permite interpolación, directivas y binding reactivo.
    • Soporta sintaxis extendida con v-if, v-for, v-bind, v-model.
  • Routing
    • Manejo de navegación con Vue Router.
    • Soporta rutas dinámicas, lazy loading, nested routes.
    • Integración con history API y transición entre vistas.
  • Components
    • Unidad principal de reutilización y encapsulación.
    • Comunicación entre componentes:
      • Props → flujo descendente
      • Emits → flujo ascendente
      • Provide/Inject → comunicación profunda
    • Componentes funcionales, slots y scoped slots.
  • State Management (Pinia vs Vuex)
    • De Vuex a Pinia, la gestión de estados definitiva para Vue-
    • Getting Started Pinia-getting-started.html
    • Introduction Pinia-introduction.html
    • Pinia vs Vuex Guía Comparativa ¿Cuál es Mejor-pinia-vs-vuex-cual-es-mejor

    • Pinia
      • API moderna basada en Composition API.
      • Tipado automático con TypeScript.
      • Soporte para devtools avanzado.
      • Mutaciones no obligatorias; sintaxis más simple.
    • Vuex
      • Más verboso, basado en opciones.
      • Enfocado en un patrón más predecible con Mutations/Actions.
      • Aún útil en apps legacy.
    • Composition API
      • Unificación lógica y reusabilidad mejorada.
      • Hooks internos (computed, ref, reactive, watch).
      • Mejora la escalabilidad de proyectos grandes.
  • Build
    • Automatizacion y Build
    • Bundlers recomendados:
      • Vite (el estándar actual por velocidad y DX).
      • Webpack solo para proyectos legacy.
    • Soporte para HMR y tree-shaking nativo.
  • Virtual DOM
    • Optimización del render mediante un DOM virtual.
    • Comparación eficiente entre estados previos y nuevos.
    • Menor coste en operaciones de UI complejas.
  • Reactividad
    • Basada en proxies.
    • ref, reactive, computed, watch, effectScope.
    • Sistema eficiente para detectar dependencias y actualizar vistas.
  • Directivas
    • v-if, v-for, v-bind, v-on, v-show, v-model.
    • Directivas personalizadas para comportamiento específico.
  • Framework progresivo
    • Aprende-gradualmente: desde pequeños widgets hasta grandes SPAs.
    • Integración fácil con proyectos existentes.
  • Usar create en vez de CLI tool
    • Recomendado usar: npm create vue@latest
    • CLI tradicional (vue-cli) está deprecado.
    • create-vue integra Vite por defecto.

      vuejs — conceptos avanzados

      arquitectura del framework

  • Runtime + Compiler
    • Vue ofrece compilación en tiempo de construcción y también en el navegador.
    • El compilador transforma templates en funciones render altamente optimizadas.
    • El runtime gestiona el re-render reactivo.
  • Options API vs Composition API
    • Options API sigue siendo válida para proyectos pequeños o legacy.
    • Composition API es el estándar moderno:
      • Mayor reutilización lógica.
      • Mejor organización interna.
      • Tipado más robusto con TypeScript.

ecosistema oficial

  • Vue Router
    • Protección de rutas (guards).
    • Transiciones entre vistas.
    • Rutas anidadas, rutas hijas dinámicas, alias y redirecciones.
  • Pinia (state)
    • Stores más pequeños y modulables.
    • Plugins para persistencia, undo/redo, logger.
    • Integración con SSR.
  • Vite
    • Dev server ultra rápido.
    • Soporte nativo para TypeScript, JSX y HMR.
    • Configuración sencilla con vite.config.js.

server-side rendering (SSR)

  • Nuxt.js
    • Meta-framework basado en Vue.
    • SSR, SSG, routing automático.
    • APIs server-side integradas (Nitro).
    • Perfecto para SEO, apps complejas o contenido dinámico.
  • Hydration
    • Proceso donde el cliente toma el HTML generado por el servidor y lo hace interactivo.
    • Vue soporta hydration parcial y optimizada.

performance y optimización

  • Lazy Loading
    • Dividir el bundle en partes y cargar vistas bajo demanda.
    • Mejora inicial de rendimiento en apps grandes.
  • Memoización con computed
    • Cálculo caché dependiente de estado reactivo.
    • Evita re-render innecesario.
  • Suspense
    • Permite mostrar estados de carga declarativos.
    • Integración natural con componentes async.
  • Teleport
    • Renderiza contenido fuera del árbol del componente.
    • Ideal para modales, overlays y tooltips.

patrones avanzados

  • Render Functions & JSX
    • Control granular sobre el DOM virtual.
    • Útil para bibliotecas UI o componentes altamente dinámicos.
  • Custom Composables
    • Encapsulación de lógica compleja en funciones reutilizables:
      • useFetch
      • useForm
      • useDarkMode
  • Provide / Inject avanzado
    • Flujo de datos profundo en árbol de componentes.
    • Ideal para temas, i18n, stores simples.
  • Plugins
    • Añaden funcionalidades globales a la app.
    • Ejemplos: trackers, gestores de errores, formateadores.

testing

  • Vitest
    • Reemplazo moderno a Jest.
    • Integración natural con Vite + Vue.
  • Vue Test Utils
    • Testing unitario de componentes.
    • Renderizado aislado, mocks y simulación de eventos.

tooling y productividad

  • TypeScript
    • Soporte nativo en SFC (<script setup lang="ts">).
    • Tipos para props, emits y stores Pinia.
  • Devtools
    • Inspección del estado, componentes, rutas y stores.
    • Time-travel debugging.
  • SFC <script setup>
    • Sintaxis más compacta.
    • Eliminación de boilerplate.
    • Importaciones automáticas (con unplugin-auto-import).

integraciones comunes

  • UI frameworks
    • Element Plus
    • Vuetify
    • Naive UI
    • Quasar
  • Internacionalización
    • Vue I18n con lazy loading de idiomas.
    • Soporte para fallback, plurales y formatos de tiempo/moneda.
  • Animaciones
    • Transition y TransitionGroup.
    • Integración fluida con GSAP o Motion One.

ejemplos de código

ejemplo — componente básico

<script setup>
import { ref } from 'vue'

const count = ref(0)
const increment = () => count.value++
</script>

<template>
<button @click="increment">Clicks: {{ count }}</button>
</template>

`

ejemplo — store pinia

import { defineStore } from 'pinia'

export const useCounter = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
	inc() { this.count++ }
}
})

ejemplo — composable

import { ref, onMounted } from 'vue'

export function useFetch(url) {
const data = ref(null)
const loading = ref(true)

onMounted(async () => {
	const res = await fetch(url)
	data.value = await res.json()
	loading.value = false
})

return { data, loading }
}

recursos recomendados

  • Documentación oficial: Vue.js Guide
  • Router: https://router.vuejs.org
  • Pinia: https://pinia.vuejs.org
  • Vite: https://vitejs.dev
  • Nuxt: https://nuxt.com

vuejs 2025 — estado actual, novedades y buenas prácticas

visión general y contexto

  • Vue.js sigue siendo un framework progresivo centrado en la capa “view”.
  • Vue 3 es el estándar desde hace años, con todo el ecosistema alineado: Router, Pinia, Vite, Devtools.
  • El enfoque modular sigue siendo clave: eliges solo lo que necesitas.

principales cambios y mejoras recientes (2024–2025)

  • Rendimiento (Core + Vite)
    • Parser de templates más rápido.
    • Optimizaciones en el sistema de reactividad y efectos.
    • Vite es la herramienta de build por defecto:
      • Arranque inmediato.
      • HMR sin retrasos.
      • Tree-shaking y bundles optimizados.
  • DX modernizada
    • Pinia reemplaza definitivamente a Vuex.
    • DevTools con mejor inspección, timeline, profiling y análisis de rendimiento.
    • Mejor integración con TypeScript.
  • Ecosistema
    • VitePress estable como SSG moderno.
    • Nuxt (3.x → 4.x) como meta-framework consolidado para SSR/SSG.

buenas prácticas recomendadas en 2025

  • Usa Composition API + <script setup> + TypeScript para mayor claridad y escalabilidad.
  • Usa Pinia para estado global.
  • Usa Vite para cualquier proyecto Vue moderno.
  • Para SSR/SSG/SEO, usa Nuxt.
  • Evita librerías o plugins que sigan anclados en Vue 2.

estado del ecosistema 2025

  • Compatibilidad con Vue 2 es mínima: la mayoría de librerías ya no la soportan.
  • Pinia 3 consolida su orientación únicamente a Vue 3.
  • Ecosistema más uniforme en torno a:
    • TypeScript
    • Composition API
    • ESM
    • Vite

tendencias 2025

  • Mayor adopción de Vitest como estándar de testing.
  • Crecimiento de meta-frameworks centrados en “frontend + server + SSG/SSR”.
  • Expansión de herramientas de DX: auto-imports, inspección en tiempo real, visualizadores de dependencias.

recursos oficiales y actualizados (formato obsidian)

Vue.js — Cheatsheet Completo (2025)

setup básico

crear proyecto

npm create vue@latest

`

estructura típica

/src
	/components
	/pages
	/composables
	/stores
	/router
	/assets

single file components (SFC)

script setup (recomendado)

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

template

<template>
	<p>{{ count }}</p>
</template>

estilos scoped

<style scoped>
p { color: #42b883; }
</style>

reactividad

ref

const n = ref(0)
n.value++        // siempre .value

reactive

const user = reactive({ name: 'Ana', age: 20 })
user.age++

computed

const total = computed(() => price.value * qty.value)

watch

watch(count, (newVal, oldVal) => {
	console.log(newVal)
})

watchEffect

watchEffect(() => {
	console.log(user.age)
})

props y comunicación

props

<script setup>
defineProps({
	title: String,
	size: { type: Number, default: 20 }
})
</script>

emits

<script setup>
const emit = defineEmits(['save'])
emit('save', { id: 1 })
</script>

slots

<slot name="header" />

directivas esenciales

  • v-if, v-else-if, v-else
  • v-for="item in list"
  • v-bind="props":prop
  • v-on="events"@click
  • v-model (form controls y componentes)
  • v-show (toggle CSS display)
  • v-html (⚠️ sanitizar)

hooks del ciclo de vida

onMounted(() => {})
onUnmounted(() => {})
onUpdated(() => {})
onBeforeMount(() => {})
onBeforeUpdate(() => {})
onBeforeUnmount(() => {})

router (Vue Router)

definir rutas

import { createRouter, createWebHistory } from 'vue-router'

const routes = [
	{ path: '/', component: Home },
	{ path: '/user/:id', component: User, props: true }
]

export const router = createRouter({
	history: createWebHistory(),
	routes
})
router.push('/dashboard')
router.push({ name: 'user', params: { id: 10 } })

ruta actual

const route = useRoute()
console.log(route.params.id)

pinia (state management)

crear store

import { defineStore } from 'pinia'

export const useCounter = defineStore('counter', {
	state: () => ({ n: 0 }),
	actions: {
		inc() { this.n++ }
	}
})

usar store

const counter = useCounter()
counter.inc()

composables (Composition API)

crear un composable

export function useFetch(url) {
	const data = ref(null)
	const loading = ref(true)

	onMounted(async () => {
		const res = await fetch(url)
		data.value = await res.json()
		loading.value = false
	})

	return { data, loading }
}

uso

const { data, loading } = useFetch('/api/posts')

patrones comunes

debounced reactive watcher

import { watch } from 'vue'
import debounce from 'lodash.debounce'

watch(searchTerm, debounce(val => {
	console.log('Buscando:', val)
}, 300))

two-way binding personalizado

defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])

function update(v) {
	emit('update:modelValue', v)
}

optimización

lazy loading de componentes

const Modal = defineAsyncComponent(() => import('./Modal.vue'))

teleport

<teleport to="#modals">
	<MyModal />
</teleport>

Suspense (componentes async)

<Suspense>
	<template #default>
		<AsyncComponent />
	</template>
	<template #fallback>
		Cargando...
	</template>
</Suspense>

animaciones

transición simple

<transition name="fade">
	<p v-if="show">Hola</p>
</transition>

<style>
.fade-enter-active, .fade-leave-active { transition: opacity .3s; }
.fade-enter-from, .fade-leave-to { opacity: 0; }
</style>

testing (Vitest)

import { mount } from '@vue/test-utils'
import { describe, it, expect } from 'vitest'
import Counter from './Counter.vue'

describe('Counter', () => {
	it('incrementa', () => {
		const wrapper = mount(Counter)
		wrapper.find('button').trigger('click')
		expect(wrapper.text()).toContain('1')
	})
})

tips avanzados (2025)

  • Usa <script setup> siempre que sea posible.
  • Usa auto-imports (unplugin-auto-import, unplugin-vue-components).
  • Evita librerías no migradas a Vue 3.
  • Usa Pinia en lugar de Vuex.
  • Divide la lógica en composables pequeños y atómicos.
  • Coloca lógica compleja fuera del template (no en v-if largos).
  • Para SSR/SSG usa Nuxt.
  • Aprovecha las DevTools para perf y traceo de renders.
  • Usa defineModel (cuando exista en tu versión) para simplificar v-models personalizados.

recursos recomendados

Vue.js — Cheatsheet avanzado (2025)

*(Solo técnicas, patrones y particularidades)

patrones de reactividad avanzados

getters reactivos sin computed

const state = reactive({ a: 1, b: 2 })
const sum = () => state.a + state.b

`

refs esquematizados (shallow)

const user = shallowRef({ name: 'Ana' })
user.value.name = 'Luis'   // no dispara reactividad
user.value = { name: 'Marta' } // sí reacciona

readonly + shallowReadonly

const config = readonly({ theme: 'dark' })

técnicas modernas con <script setup>

definir props + emits con tipos

<script setup lang="ts">
const props = defineProps<{ id: number; active?: boolean }>()
const emit = defineEmits<{ (e: 'toggle', v: boolean): void }>()
</script>

inyección de tipos a slots

<script setup lang="ts">
interface Slots {
default: (props: { msg: string }) => any
}
const slots = defineSlots<Slots>()
</script>

control de flujo y optimización del render

v-memo — evitar renders innecesarios

<div v-memo="[user.id]">{{ user.name }}</div>

v-once para contenido estático

<h1 v-once>{{ title }}</h1>

fragmentos condicionales eficientes

<template v-if="ok">
<A />
<B />
</template>

técnicas de routing avanzadas

props dinámicos directamente desde la ruta

{
path: '/u/:id',
component: User,
props: route => ({ id: Number(route.params.id) })
}

suspender navegación hasta una promesa

router.beforeEach(async () => {
await fetch('/check-session')
})

scroll inteligente

scrollBehavior(_, __, saved) {
return saved ?? { top: 0 }
}

patrones profesionales con Pinia

stores dinámicos por instancia

export const useScoped = (scope) =>
defineStore(`store-${scope}`, { state: () => ({ n: 0 }) })()

hidratar store desde SSR / persistencia

const store = useUserStore()
store.$patch(JSON.parse(localStorage.user))

interceptar acciones

store.$onAction(({ name, args, after }) => {
after(() => console.log(`${name} OK`, args))
})

composables avanzados

composable con abort controller

export function useAbortableFetch(url) {
const data = ref(null)
const controller = new AbortController()

const run = async () => {
	const res = await fetch(url, { signal: controller.signal })
	data.value = await res.json()
}

onUnmounted(() => controller.abort())

return { data, run }
}

exposiciones selectivas

defineExpose({
refresh() { /* … */ }
})

usar instancias globales dentro de composables

const router = useRouter()
const route = useRoute()

particularidades del template

key inteligente en listas derivadas

<li v-for="item in list" :key="item.id ?? item.name">

slots + fallbacks

<slot name="footer">Default footer</slot>

eventos nativos en componentes

<MyInput @focus.native="onFocus"/>

utilidades del runtime útiles para pro apps

nextTick

await nextTick()
// DOM ya actualizado

definir componentes inline

<component :is="dynamicComponent"/>

reutilizar watchers de forma programática

const stop = watch(source, handler)
// …
stop()

patrones recomendados de arquitectura 2025

  • Organiza logic en composables atómicos, no en mega-composables.
  • Separa UI components de feature components.
  • Usa auto-imports para composables, stores y componentes.
  • Evita usar v-if y v-for en el mismo nodo (divide el nodo).
  • Para listas grandes usa virtual scrollers (Vue Virtual Scroll List, virtua).
  • Prefiere eventos específicos en vez de estados globales innecesarios.
  • Usa async components para rutas pesadas.
  • Para formularios complejos usa librerías tipadas (FormKit, Vee-Validate).

patrones avanzados de integrate con API

gestión de cache manual reactiva

const cache = reactive(new Map())

async function fetchCached(key, fn) {
if (!cache.has(key)) cache.set(key, await fn())
return cache.get(key)
}

manejar estados: idle / loading / success / error

const state = reactive({
status: 'idle', data: null, error: null
})

async function run() {
try {
	state.status = 'loading'
	const res = await fetch('/api')
	state.data = await res.json()
	state.status = 'success'
} catch (e) {
	state.status = 'error'
	state.error = e
}
}

utilidades poco conocidas pero muy útiles

defineOptions

<script setup>
defineOptions({
name: 'MyComp'
})
</script>

v-model múltiple

<MyComponent v-model:email="email" v-model:name="name" />

useAttrs para pasar attrs rest a elementos raíz

const attrs = useAttrs()

useSlots para verificar presencia de slots

const slots = useSlots()
if (slots.header) { /* … */ }

herramientas útiles 2025

  • Vetur → Vue Language Features (Volar) (mejor TS + DX)
  • unplugin-auto-import (composables automáticos)
  • unplugin-vue-components (componentes auto-registrados)
  • VueUse (colección enorme de composables de calidad)
  • FormKit / VeeValidate para formularios robustos
  • Vitest + Test Utils para testing

enlaces útiles

Vue.js — Composition API

Introducción

La Composition API es el modelo moderno de Vue.js para organizar lógica reutilizable, mejorar escalabilidad y ofrecer mayor control sobre el ciclo de vida y la reactividad. Permite separar la lógica por funcionalidades, no por opciones, evitando fragmentación y facilitando testing.

Fundamentos Esenciales

Setup()

El punto de entrada para usar Composition API. Dentro de setup() defines estado reactivo, computed, watchers, lifecycle hooks y retornas las propiedades/métodos que expondrás al template.

Ejemplo básico

import { ref } from 'vue'

export default {
	setup() {
		const count = ref(0)
		const inc = () => count.value++

		return { count, inc }
	}
}

`


Reactividad

ref()

Crea un valor reactivo primitivo o no primitivo con .value. Ideal para valores simples.

const nombre = ref('Edu')
nombre.value = 'Carlos'

reactive()

Convierte un objeto entero en reactivo. Útil para estados complejos.

const state = reactive({
	user: null,
	loading: false
})

toRefs() y toRef()

Evitan perder reactividad cuando extraes propiedades de un objeto reactivo.

const { user, loading } = toRefs(state)

Computed y Watchers

computed()

Propiedades derivadas, con caching por defecto.

const fullName = computed(() => user.value.name + ' ' + user.value.surname)

watch()

Observa cambios específicos.

watch(() => state.user, (nuevo, viejo) => {
	console.log('cambio usuario', nuevo)
})

watchEffect()

Ejecuta automáticamente cuando cualquier dependencia es usada dentro del callback.

watchEffect(() => {
	console.log(state.loading)
})

Lifecycle Hooks

Versión Composition API de los hooks del Options API.

  • onMounted()
  • onUnmounted()
  • onUpdated()
  • onBeforeMount()
  • onBeforeUpdate()
  • onBeforeUnmount()
onMounted(() => {
	console.log('Montado!')
})

Dependencias e Inyección (provide / inject)

Permiten compartir estado entre componentes sin pasar props manualmente.

// padre
provide('theme', 'dark')

// hijo
const theme = inject('theme')

Reutilización de Lógica — Composables

Los composables son funciones que encapsulan lógica reutilizable usando Composition API.

Reglas:

  • Deben comenzar con useX
  • Devuelven estado reactivo + funciones
  • Pueden usar cualquier API de Composition

Ejemplo:

// useFetch.js
export function useFetch(url) {
	const data = ref(null)
	const loading = ref(true)

	onMounted(async () => {
		data.value = await fetch(url).then(r => r.json())
		loading.value = false
	})

	return { data, loading }
}

Manejo de Tipos (TypeScript)

La Composition API fue diseñada para integrarse perfectamente con TS.

const count = ref<number>(0)
const user = reactive<{ name: string; age: number }>({ name: '', age: 0 })

Reglas especiales de la Composition API

Reglas en setup()

  • No usar this
  • Debe ser sincrónica
  • Evitar operaciones pesadas (usar composables o efectos)

Ventajas sobre Options API

  • Lógica agrupada por características
  • Mejor escalabilidad en equipos
  • Testing más simple
  • Reutilización avanzada (no requiere mixins)

Nuevas funcionalidades relevantes (2024–2025)

script setup (sugerido como estándar)

Hace el código más simple, menos boilerplate.

<script setup>
const count = ref(0)
</script>

<template>
	<button @click="count++">{{ count }}</button>
</template>

defineProps y defineEmits

Solo disponibles en <script setup>.

<script setup>
const props = defineProps({ msg: String })
const emit = defineEmits(['update'])
</script>

defineModel (Vue 3.4+)

Simplifica v-model personalizado.

<script setup>
const model = defineModel()
</script>

Integración con Pinia

Pinia usa Composition API internamente, por lo que encaja de manera natural.

export const useUserStore = defineStore('user', () => {
	const user = ref(null)
	const setUser = (u) => user.value = u

	return { user, setUser }
})

Buenas Prácticas (Cheats)

  • Usa script setup siempre que sea posible.
  • Separa estados complejos en composables reutilizables.
  • Usa computed para cualquier valor derivado.
  • Usa reactive() para objetos, ref() para primitivos.
  • Evita watchers innecesarios — usar computed primero.
  • Estructura composables por funcionalidades: useAuth, useTheme.
  • No mezcles Options y Composition en el mismo archivo sin necesidad.
  • Exporta solo lo mínimo necesario desde composables.
  • Composables nunca deben manipular DOM directamente.