Plantillas y sintaxis básica
Las plantillas en Vue 2 permiten inseratr datos dinámicos mediante interpolación y expresiones JavaScript. La sintaxis de doble llaves se usa para mostrar valores reactivos.
<template>
<div>
<p>Texto interpolado: {{mensaje}}</p>
<p>Expresión JS: {{estado ? 'activo' : 'inactivo'}}</p>
</div>
</template>
<script>
export default {
data() {
return {
mensaje: 'Hola Vue',
estado: true
}
}
}
</script>
Las propiedades fundamentales de un componente incluyen:
- data: Almacena el estado reactivo del componente.
- props: Define datos que se reciben del componente padre.
- computed: Propiedades calculadas con caché automático.
- methods: Funciones que responden a eventos del usuario.
- watch: Observadores para reaccionar a cambios en los datos.
- components: Regsitra subcomponentes disponibles en la plantilla.
Directivas principales
v-if/v-else-if/v-else: Renderizado condicional completo.v-show: Alterna la visibilidad mediante CSS.v-for: Renderizado de listas iterando arrays u objetos.v-bind(:): Enlace dinámico de atributos HTML.v-on(@): Escucha eventos del DOM.v-model: Enlace bidireccional para formularios.v-text: Establece el contenido de texto de un elemento.v-html: Renderiza HTML (con precaución por riesgos XSS).
Propiedades computadas versus observadores
Las propiedades computadas se definen en la sección computed y ofrecen valores derivados con caché. Son ideales para transformaciones de datos complejas que se usan en múltiples lugares.
<template>
<div>
<p>Nombre completo: {{nombreCompleto}}</p>
<button @click="actualizar">Actualizar</button>
</div>
</template>
<script>
export default {
data() {
return {
usuario: {
nombre: 'Ana',
apellido: 'García'
}
}
},
computed: {
// Sintaxis de función (solo lectura)
nombreCompleto() {
return `${this.usuario.nombre} ${this.usuario.apellido}`;
},
// Sintaxis de objeto (lectura y escritura)
nombreMayusculas: {
get() {
return this.usuario.nombre.toUpperCase();
},
set(nuevoValor) {
this.usuario.nombre = nuevoValor.toLowerCase();
}
}
},
methods: {
actualizar() {
this.nombreMayusculas = 'CARLOS';
}
}
}
</script>
Los observadores (watch) monitorizan cambios en propiedades específicas del estado.
export default {
data() {
return {
configuracion: {
tema: 'claro',
idioma: 'es'
},
busqueda: ''
}
},
watch: {
// Observador simple para un valor primitivo
busqueda(valorNuevo, valorAnterior) {
console.log(`Búsqueda cambiada de "${valorAnterior}" a "${valorNuevo}"`);
},
// Observador profundo para objetos
configuracion: {
handler(nuevaConfig) {
console.log('Configuración actualizada:', nuevaConfig);
},
deep: true, // Para observar cambios internos del objeto
immediate: false // Ejecutar al crear el componente (por defecto false)
}
}
}
Diferencias clave
| Característica | Propiedad computada | Observador |
|---|---|---|
| Almacenamiento | Cachea resultados | Ejecuta función en cada cambio |
| Operaciones asíncronas | No permitidas | Soportadas |
| Uso principal | Datos derivados (uno a varios) | Efectos secundarios (varios a uno) |
| Retorno de valor | Requiere return explícito | No aplica |
Clases y estilos dinámicos
Vue permite aplicar clases y estilos de forma dinámica usando sintaxis de objetos o arrays.
Clases CSS
<div :class="clasesElemento"></div>
<div :class="[claseBase, claseDinamica]"></div>
<script>
export default {
data() {
return {
activo: true,
error: false,
clasesElemento: {
'activo': this.activo,
'error-critico': this.error
}
}
}
}
</script>
Estilos en línea
<div :style="estilosReactivos"></div>
<div :style="[estilosBase, estilosDinamicos]"></div>
<script>
export default {
data() {
return {
colorPrimario: '#3498db',
estilosReactivos: {
color: this.colorPrimario,
fontSize: '14px'
}
}
}
}
</script>
Renderizado condicional
Para mostrar u ocultar elementos según condiciones, Vue ofrece dos aproximaciones:
v-if: Elimina y recrea el elemento del DOM. Ideal para condiciones que raramente cambian.v-show: Alterna la visibilidad con CSS (display: none). Mejor para cambios frecuentes.
<div v-if="mostrarContenido">
Contenido renderizado condicionalmente
</div>
<div v-show="mostrarAviso">
Aviso que se oculta con CSS
</div>
Renderizado de listas
El iterador v-for permite recorrer arrays y objetos. Se recomianda usar una clave única (:key) para optimizar el rendimiento.
<!-- Iterar array -->
<ul>
<li v-for="(producto, indice) in productos" :key="producto.id">
{{indice + 1}}. {{producto.nombre}}
</li>
</ul>
<!-- Iterar objeto -->
<ul>
<li v-for="(valor, clave) in datosUsuario" :key="clave">
{{clave}}: {{valor}}
</li>
</ul>
<!-- Iterar rango numérico -->
<div v-for="pagina in 5" :key="pagina">
Página {{pagina}}
</div>
Nota importante: Evitar combinar v-for y v-if en el mismo elemento. En Vue 2, v-for tiene mayor prioridad, lo que puede causar comportamientos inesperados.
Manejo de eventos
Los eventos se enlazan con la directiva v-on o su alias @, seguido de modificadores específicos.
<button @click="enviarFormulario">Enviar</button>
<div @mousemove.throttle="actualizarCoordenadas">Área de seguimiento</div>
<!-- Modificadores de eventos -->
<form @submit.prevent="handleSubmit">
<button @click.stop="clickInterno">Click sin propagar</button>
<a @click.prevent="navegar">Enlace sin redirección</a>
</form>
Modificadores disponibles
.stop:event.stopPropagation().prevent:event.preventDefault().capture: Escucha en fase de captura.self: Solo si el evento se originó en el elemento.once: Ejecutar solo una vez.passive: Mejora rendimiento en eventos de scroll
Vinculación de formularios
v-model proporciona un azúcar sintáctico para el enlace bidireccional en elementos de formulario.
<!-- Texto -->
<input type="text" v-model="campoTexto">
<textarea v-model="campoLargo"></textarea>
<!-- Checkbox -->
<input type="checkbox" v-model="aceptaTerminos">
<!-- Radio -->
<input type="radio" v-model="seleccion" value="opcion1">
<!-- Select -->
<select v-model="paisSeleccionado">
<option value="mx">México</option>
<option value="es">España</option>
</select>
Modificadores de v-model
.lazy: Sincronizar en eventochangeen vez deinput.number: Convertir automáticamente a número.trim: Eliminar espacios en blanco extremos
<input v-model.trim="textoLimpio">
<input v-model.number="edad">
<input v-model.lazy="valorSync">