FRAMEWORKS
FRONT


UN , ¿FREIM WORK?
Conjunto de herramientas, librerías y/o técnicas que nos permiten resolver un problema de una manera más elegante, sencilla y que nos permitirá resolver problemas nuevos similares de la misma manera.
Muchos frameworks nos proporcionan una estructura del proyecto ha seguir y siempre la misma, muchos framworks nos facilitan resolver problemas comunes de manera sencilla (digamos que, como jquery lo hacía con la manipulación del dom) etc etc
La web se vuelve muy dinámica
Tanto, que ya no se le llaman webs, y nace el concepto de
WEBAPPS
FACEBOOK, WHATSAPP WEB, SPOTIFY, APLICACIONES MÓVILES HÍBRIDAS, APLICACIONES DE ESCRITORIO CON ELECTRON
También nace el concepto de:
Single Page Application <=> SPA
index.html
<div>
</div>
Ejemplos WebApps y SPA


Ejemplos WebApps y SPA
Ejemplos WebApps y SPA

OJO, clara diferencia entre SPA y no SPA

Ordenador usuario
Servidor facebook
== DAME EL index.HTML =>
<= Toma el index.html ==
== El usuario navega a categories.html =>
Web estática ( NO SPA )
Se refresca la pantalla
== NAVEGO a categorias.html =>
<= Toma el categorias.html ==
Se refresca la pantalla
Dame todos los ficheros
Toma los scripts y los css
Dame todos los ficheros
Toma los scripts y los css
Ordenador usuario
Servidor facebook
== DAME EL index.HTML =>
<= Toma el index.html ==
== El usuario navega a categories.html =>
Single Page Application
Se refresca la pantalla
== NAVEGO a categorias.html =>
<= Toma el categorias.html ==
Se dibuja dentro del contenedor
Dame todos los ficheros
Toma los scripts y los css
Ordenador usuario
Servidor facebook
== DAME EL index.HTML =>
<= Toma el index.html ==
== El usuario navega a categories.html =>
Single Page Application
Se refresca la pantalla
NAVEGO a categorias.html
Me autosirvo el template
Me renderizo una cosa nueva
Dame todos los ficheros
Toma los scripts y los css
MILES DE FRAMEWORKS
REACT
EMBER
BACKBONES
ANGULAR
VUEJS
ETC ETC ...

Crear proyecto
- Se recomienda leer el Quick Start de la documentación.

Crear proyecto
- Se recomienda leer el Quick Start de la documentación.


Proyecto vue

Anteriormente, se usaba la estructura de webpack, ahora se parece más y concuerda con la típica estructura de Vite.
¿Te recuerda al mkweb?
¿Cómo usaremos vue nosotros?
Pues mediante los comandos del package.json
pnpm dev / pnpm run build

.VUE
Vamos a trabajar con la "Options"

inside export default
<script>
export default {
name : 'todo-list',
data () {
return {
name : 'Pruebas'
}
}
}
</script>
- data:
- components:
- methods:
- watch:
- computed:
- created:
- mounted:
- updated:
- ...
TEMPLATING

Imagina que necesitas, representar en la pantalla un usuario, o recoger de un formulario los valores del nuevo usuario
Antes de vue, con jquery y ordenadito
<div class="usuario">
<h1 id="nombre"></h1>
<input type="number" id="edad"/>
</div>
function dibujarUsuario (usuario) {
$('#nombre').text(usuario.nombre);
$('#edad').val(usuario.edad);
}
function recogerValores(){
var nombre = $('#nombre').text();
var edad = $('#edad').val();
}
Con vuejs, esto se consigue en ...
ZERO LINES

data
<template>
<div>
<h1> My name is {{ user.name }} </h1>
<h2> I am {{ user.age }} years old </h2>
</div>
</template>
<script>
export default {
name : 'user-element',
data() {
return {
user : {
name : 'Jhon Doe',
age : 20
}
}
}
}
</script>
{{data}}
<template>
<div>
<h1> My name is {{ name }} </h1>
<h2 v-once> I am {{ age }} years old </h2>
<textarea v-html="description"></textarea>
</div>
</template>
Relación modelo => vista
data
<template>
<div>
<h1> My name is {{ name }} </h1>
<h2> I am {{ age }} years old </h2>
<textarea v-html="description"></textarea>
<input v-model="age" type="number">
</div>
</template>
Relación vista => modelo
¿ Y si tienes un array de usuario ?
v-for
<template>
<div class="users">
<div v-for="user in users">
<h1> My name is {{ user.name }} </h1>
<h2> I am {{ user.age }} years old </h2>
<textarea v-html="user.description"></textarea>
<input v-model="user.age" type="number">
</div>
</div>
</template>
export default {
name : 'user-element',
data () {
return {
users: [{} , {}]
}
}
}
Más cosas
v-on y methods
<!-- Este sería sin pasar parámetros, simplemente asociamos -->
<button v-on:click="addUser" > Añadir </button>
<!-- Este sería si quieres pasar parámetros -->
<button v-on:click="addUser('paco', 20)" > Añadir </button>
export default {
data () {
return { ... }
},
methods : {
addUser (parametros) {
...
}
}
}
method, this
export default {
name: "user-element",
data() {
return {
user: {
name: "",
age: 0,
description: "",
email: ""
}
};
},
methods: {
add() {
console.log('Datos usuario:');
console.log(this.user);
}
},
}


method, this
export default {
name: "user-element",
data() {
return {
user: {
name: "",
age: 0,
description: "",
email: ""
}
};
},
methods: {
add() {
console.log('Datos usuario:');
console.log(this.user);
}
},
}


method, this
methods: {
add() {
if ( this.validateUser(this.user) ){
console.log('Validado');
}
},
validateUser (user) {
return true;
}
},

OJO
methods: {
add() {
if ( validateUser(this.user) ){
console.log('Validado');
}
},
validateUser (user) {
return true;
}
},

OJO, DANGER ! () =>
methods: {
add : () => {
if ( this.validateUser(this.user) ){
console.log('Validado');
}
},
validateUser (user) {
return true;
}
},

v-on keymodifiers
<button v-on:click="addUser" > Añadir </button>
<input
placeholder="Introduce el nombre"
v-model:"user.name"
v-on:blur="validateName"
v-on:keyup.enter="validateName"
v-on:focus="showTip"
/>
v-on y modificadores
<input
placeholder="Introduce el nombre"
v-model:"user.name"
v-on:blur="validateName"
v-on:keyup.mouseenter.once="showTip"
/>
<button v-on:click.prevent="addUser" > Añadir </button>
Más cosas
v-bind:attr
<img
v-bind:src="image.link"
v-bind:alt="image.alt"
v-bind:title="image.title"
/>
<a v-bind:href="nuevaRuta"> pincha aquí </a>
v-bind:attr
<img
v-bind:class="image.classes"
/>
<div
class="user"
v-bind:class="{ 'isActive' : user.isActive }"
></div>
Se aplicará la clase 'isActive' si la condicion de la derecha se cumple, en esa caso, si la variable user.isActive da true
Le puedes pasar un array de clases [ 'clase1, 'clase2']
v-bind:style
<div
class="user"
v-bind:style="{ propiedad : valor , fontSize : user.fuente, color : user.color }"
></div>

Vamos a poner esto en práctica
Hacemos proyecto todo-list en directo de cero con mi ayuda
Una cosa más
v-if v-else v-else-if
<div class="user">
<h1> Mi nombre es {{user.name}}</h1>
<p v-if="mostrarEdad"> Tengo {{user.age}} años</p>
<button @click="mostrarEdad = !mostrarEdad">Mostrar edad</button>
</div>
<script>
export default {
data () {
return {
mostrarEdad : false
}
}
}
</script>

Una cosa más
v-if v-else v-else-if
<div class="user">
<h1> Mi nombre es {{user.name}}</h1>
<p v-if="mostrarEdad"> Tengo {{user.age}} años</p>
<p v-if="!mostrarEdad"> No te puedo decir mi edad</p>
<button
@click="mostrarEdad = !mostrarEdad"
v-if="!mostrarEdad"
>Mostrar edad</button>
<button
@click="mostrarEdad = !mostrarEdad"
v-else
>Ocultar edad</button>
</div>

"Mini break de teoria"
Os toca a ustedes ahora
Hacer el tutorial que tiene vuejs hasta el paso 7 de manera individual

Más cosas
computed
<ul class="lista-compra">
<li v-for="item in items"> {{item.name}} x {{ item.price }}€</li>
</ul>
<p> Precio total : {{ totalPrice }} </p>
export default {
name: 'App',
data () : ...,
computed : {
totalPrice () {
let result = 0;
this.items.forEach( item => result += item.price)
return result;
}
}
};
computed
<div class="users">
<div
class="user"
v-for="user in usersFiltered">
</div>
</div>
computed : {
usersFiltered () {
let results = [];
results = /* only user.name.includes() */;
if (this.onlyWatchNotContacted){
results = /* only !user.contacted */
}
/* More filters */
return results;
}
}
watch
<input v-model="user.name">
<small v-if="errors.nameInvalid">
El nombre de usuario introducido no es válido
</small>
watch : {
'user.name' () {
let isValid = /* do things */;
this.errors.invalidName = isValid;
}
}
watch

watch
<input type="text" placeholder="nombre"
v-model="nuevo.name"
@keyup.enter="add">
watch : {
'nuevo.name': function () {
console.log(this.nuevo.name);
if (this.nuevo.name.toLowerCase() === 'pera'){
alert('está prohibido comprar peras');
this.nuevo.name = '';
}
}
},
Invalidad un botón
<input type="text" placeholder="Nuevo todo"
v-model="newTodo.title">
<button :disabled="newTodoIsInvalid"
@click="add"> Añadir </button>
watch : {
'newTodo.title': function () {
if ( /* invalid */ )
this.newTodoIsInvalid = true;
else
this.newTodoIsInvalid = false;
}
},
Invalidad un botón
<input type="text" placeholder="Nuevo todo"
v-model="newTodo.title">
<button :disabled="newTodoIsInvalid"
@click="add"> Añadir </button>
computed : {
newTodoIsInvalid: function () {
if ( /* invalid */ )
return true;
else
return false;
}
},
Mejor usar un computed para estas cosas

<script>
import axios from 'axios';
export default {
name: "lista",
data() {
return {
users: []
}
},
mounted() {
// Uso axios para cargar los datos
axios.get()
.then(res => res.data)
.then(data => {
this.users = data;
})
}
}
</script>
<template>
<div> Listado de usuarios </div>
<!-- v-for mostrando usuarios -->
<div class="user"> </div>
</template>
Más ejercicios para practicar

Ejercicio en grupo

Paso 1. pnpm install axios
Hacemos un CRUD con la API de
https://retool.com/api-generator
C = Create , R = Read , U = Update , D = Delete
Curso de Programación web CLM Marzo 2025. VueJS
By Yunior González Santana
Curso de Programación web CLM Marzo 2025. VueJS
- 42