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 ...

Instalamos Vue 3

  • Se recomienda leer el Quick Start  de la documentación. 
  • Para crear un proyecto actualmente recomiendan usar

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 

npm run dev / npm run build

.VUE

Vamos a trabajar con la "Options" 

Repasando el componente más básico

Vemos el del boilerplate

Este es el APP.vue

Creando y usando nuestro propio componente

<template>
    <h1> {{ name }} </h1>
</template>

<script>
export default {
    name : 'todo-list',
    data () {
        return {
            name : 'Pruebas'
        }
    }

}
</script>

<style scoped>
</style>

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 ?

<template>
    <div class="users">
        <div>
            <h1> My name is {{ users[0].name }} </h1>
            <h2 v-once> I am {{ users[0].age }} years old </h2>
            <textarea v-html="users[0].description"></textarea>
            <input v-model="users[0].age" type="number">
        </div>
        <div>
            <h1> My name is {{ users[1].name }} </h1>
            <h2 v-once> I am {{ users[1].age }} years old </h2>
            <textarea v-html="users[1].description"></textarea>
            <input v-model="users[1].age" type="number">
        </div>
    </div>
</template>

¡ Dibujamos todos los elementos del array de uno en uno ! 

¿ Y si tienes un array de usuario ?

... ... es coña xD ZERO LINES ! 

<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>

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"
    />
<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 todos a la vez 

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

Ejercicio Individual

 

Ejercicio Individual

  • Al introducir los 3 campos válidamente se añadirá una nueva fruta.
  • Añade una última fila a la "factura" que ponga Total : y salga el total de la compra.
  • Añade debajo una posibilidad de borrar/cancelar una compra.

Ejercicio final en grupo

Pues lo mismo pero con VueJS :P

¿ Recuerdan este ejercicio ?

https://github.com/YuniorGlez/dinamic_form

Ejercicio final en grupo

- Le ponemos validaciones a medida que el usuario va haciendo blur

- Le añadimos feedback visual si el formulario ya está correcto o si hay algo mal (deshabilitamos botón)

- Añadimos un buscador por texto y/o buscador por cada campo

Cosas que puntuan

V 2.0 Ejercicio

Importamos Axios y recogemos los usuarios la API y los mandamos a la api

https://jsonplaceholder.typicode.com/users

Router 

index.html

<router-view>

 

 

 

 

</router-view>

Vue Router

V 3.0 Ejercicio

Creamos un proyecto con router.

 

Vamos a realizar un proyecto con una vista en modo lista donde mostramos la previsualización de unos elementos, en este caso de los usuarios y donde cada cajita tiene un botón de "ver más".

 

Al clickar en ver más navegamos a /details/:id y en esta vista vamos a renderizar una vista nueva donde vamos a buscar a la api ese usuario a la API y donde mostramos todos sus campos y un botón de "volver atrás"