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-vueintegra Vite por defecto.vuejs — conceptos avanzados
arquitectura del framework
- Recomendado usar:
- 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
- Encapsulación de lógica compleja en funciones reutilizables:
- 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.
- Soporte nativo en SFC (
- 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
TransitionyTransitionGroup.- 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)
- Documentación oficial Vue.js
- Vue Router
- Pinia — State Management
- Vite
- VitePress
- Nuxt
- Blog oficial de Vue
- Blog de Nuxt
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-elsev-for="item in list"v-bind="props"→:propv-on="events"→@clickv-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
})
navegación
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-iflargos). - 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-ifyv-foren 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
computedprimero. - 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.
¿Te gusta este contenido? Suscríbete vía RSS