Diferència entre revisions de la pàgina «VUEJS»

De wikiserver
Dreceres ràpides: navegació, cerca
(Ejercicios)
(Ejercicios)
 
(57 revisions intermèdies per 3 usuaris que no es mostren)
Línia 12: Línia 12:
 
<source lang="javascript">
 
<source lang="javascript">
 
<body>
 
<body>
 
+
    <div id="el">
        <div id="el">
+
            <h1> {{mensaje}}</h1>    <!--podemos ver -->
                <h1> {{mensaje}}</h1>    <!--podemos ver -->
+
    </div>
        </div>
+
</body>
    </body>
 
 
      
 
      
    <script src="https://cdn.jsdelivr.net/npm/vue"></script> //CDN
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>  
    <script>
+
<script>
        Vue.config.devtools = true;   
+
    var variable = Vue.createApp({
        new Vue({
+
        data: () => ({
            el: '#el',  //hace referencia al elemento id= el
+
             mensaje: "resultado"  //datos, hace referencia dentro de elemento  
             data: {
 
                mensaje: "resultado"  //datos, hace referencia dentro de elemento #el {{mensaje}}
 
            }
 
 
         })
 
         })
 +
    }).mount("#el") //hace referencia al elemento id= el
 
      
 
      
   
+
</script>
    </script>
 
 
</source>
 
</source>
  
Línia 35: Línia 31:
 
<source lang="javascript">
 
<source lang="javascript">
 
<body>
 
<body>
        <div id="el">
+
    <div id="el">
                <h1>Hola <span v-text="mensaje"> </span></h1>  <!--muestra "Hola" y luego en función del texto del input va rellenando-->
+
            <h1>Hola <span v-text="mensaje"> </span></h1>  <!--muestra "Hola" y luego en función del texto del input va rellenando-->
                <input type="text" class="text" v-model="mensaje">
+
            <input type="text" class="text" v-model="mensaje">
        </div>
+
    </div>
    </body>
+
</body>
   
+
 
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
+
<script>
      
+
 
        var variable = new Vue({
+
     var variable = Vue.createApp({
            el: '#el',
+
        data: () => ({
            data: {
+
            mensaje: "resultado"
                mensaje: "resultado"
 
            }
 
 
         })
 
         })
 +
    }).mount('#el');
 
      
 
      
    </script>
+
</script>
 
</source>
 
</source>
 
  
 
===V-SHOW===
 
===V-SHOW===
Línia 70: Línia 64:
 
<script>
 
<script>
  
     var variable = new Vue({
+
     var variable = Vue.createApp({
        el: '#el',
+
         data: () => ({
         data: {
 
 
             mensaje: "resultado"
 
             mensaje: "resultado"
         }
+
         })
     })
+
     }).mount("#el")
  
  
Línia 84: Línia 77:
 
<source lang="javascript">
 
<source lang="javascript">
 
<body>
 
<body>
        <div id="el">
+
  <div id="el">
                <h1 v-show="mensaje.length > 2">Hola <span v-text="mensaje"> </span></h1>  <!--si el mensaje es mayor que 2 muestra en caso contrario hace un display:none en css-->
+
    <h1 v-show="mensaje.length > 2">Hola <span v-text="mensaje"> </span></h1>  <!--si el mensaje es mayor que 2 muestra en caso contrario hace un display:none en css-->
                <input type="text" class="text" v-model="mensaje">
+
    <input type="text" class="text" v-model="mensaje">
        </div>
+
  </div>
    </body>
+
</body>
   
+
 
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
+
<script>
   
+
 
        var variable = new Vue({
+
  var variable = Vue.createApp({
            el: '#el',
+
    data: () => ({
            data: {
+
      mensaje: "resultado"
                mensaje: "resultado"
+
    })
            }
+
  }).mount("#el")
        })
+
 
   
+
</script>
    </script>
 
 
</source>
 
</source>
  
Línia 107: Línia 99:
 
<source lang="javascript">
 
<source lang="javascript">
 
<body>
 
<body>
        <div id="el">
+
  <div id="el">
                <h1 v-if="mensaje.length > 2">Hola <span v-text="mensaje"> </span></h1>    <!--en vez de v-show podemos usar v-if-->
+
    <h1 v-if="mensaje.length > 2">Hola <span v-text="mensaje"> </span></h1>    <!--en vez de v-show podemos usar v-if-->
                <h1 v-else>otra</h1>
+
    <h1 v-else>otra</h1>
                <input type="text" class="text" v-model="mensaje">
+
    <input type="text" class="text" v-model="mensaje">
        </div>
+
  </div>
    </body>
+
</body>
   
+
 
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
+
<script>
   
+
 
        var variable = new Vue({
+
  var variable = Vue.createApp({
            el: '#el',
+
    data: () => ({
            data: {
+
      mensaje: "resultado"
                mensaje: "resultado"
+
    })
            }
+
  }).mount("#el")
        })
+
 
   
+
</script>
    </script>
 
 
</source>
 
</source>
 
  
 
===V-FOR===
 
===V-FOR===
Línia 134: Línia 124:
 
     <div id="el">
 
     <div id="el">
 
         <ul>
 
         <ul>
             <!-- <li v-text="profesores[0]"></li>-->
+
             <!-- <li v-text="profesores[0]"></li> -->
 
             <li v-for="profesor in profesores" v-text="profesor"></li>
 
             <li v-for="profesor in profesores" v-text="profesor"></li>
 
         </ul>
 
         </ul>
Línia 142: Línia 132:
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
     var variable = new Vue({
+
     var variable = Vue.createApp({
        el: '#el',
+
         data: () => ({
         data: {
 
 
             profesores: [      //utilizamos un array con cadenas
 
             profesores: [      //utilizamos un array con cadenas
 
                 "Julio Noguera",
 
                 "Julio Noguera",
 
                 "Albert Canela",
 
                 "Albert Canela",
 
                 "Alex Salinas"
 
                 "Alex Salinas"
 
 
             ]
 
             ]
         }
+
         })
     })
+
     }).mount("#el")
 
</script>
 
</script>
 
</source>
 
</source>
Línia 163: Línia 151:
 
     <div id="el">
 
     <div id="el">
 
         <ul>
 
         <ul>
             <!-- <li v-text="profesores[0]"></li>-->
+
             <!-- <li v-text="profesores[0]"></li> -->
 
             <li v-for="profesor in profesores" v-text="profesor.nombre"></li>
 
             <li v-for="profesor in profesores" v-text="profesor.nombre"></li>
 
         </ul>
 
         </ul>
Línia 171: Línia 159:
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
     var variable = new Vue({
+
     var variable = Vue.createApp({
        el: '#el',
+
         data: () => ({    //utilizamos un array con objetos
         data: {    //utilizamos un array con objetos
 
 
             profesores: [   
 
             profesores: [   
 
                 {nombre:"Julio Noguera"},
 
                 {nombre:"Julio Noguera"},
Línia 180: Línia 167:
  
 
             ]
 
             ]
         }
+
         })
     })
+
     }).mount("#el")
 
</script>
 
</script>
 
</source>
 
</source>
Línia 188: Línia 175:
  
 
<source lang="javascript">
 
<source lang="javascript">
    <div id="el">
+
<body>
 +
  <div id="el">
 
         <ul>
 
         <ul>
 
             <!-- <li v-text="profesores[0]"></li>-->
 
             <!-- <li v-text="profesores[0]"></li>-->
Línia 203: Línia 191:
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
     var variable = new Vue({
+
     var variable = Vue.createApp({
        el: '#el',
+
         data: () => ({
         data: {
 
 
             profesores: [{
 
             profesores: [{
 
                     nombre: "Julio Noguera",
 
                     nombre: "Julio Noguera",
Línia 220: Línia 207:
  
 
             ]
 
             ]
         }
+
         })
     })
+
     }).mount("#el")
 
</script>
 
</script>
  
Línia 236: Línia 223:
  
 
<source lang="javascript">
 
<source lang="javascript">
 +
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<body>
 
<body>
 
     <div id="el">
 
     <div id="el">
 
 
         <input type="text" v-model="mensaje">
 
         <input type="text" v-model="mensaje">
 
         <h1 v-text="mensaje"></h1>
 
         <h1 v-text="mensaje"></h1>
         <!-- <button @click="mensaje=mensaje.split('').reverse('').join('')">BOTON</button> <!-- @click es abreviación de v-on:click -->
+
         <!-- <button @click="mensaje=mensaje.split('').reverse('').join('')">BOTON</button> -->
 
+
        <!-- @click es abreviación de v-on:click -->
 
         <button @click="invertir">INVERTIR</button>
 
         <button @click="invertir">INVERTIR</button>
 
 
     </div>
 
     </div>
 
</body>
 
</body>
  
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
 
<script>
 
<script>
     var variable = new Vue({
+
     var variable = Vue.createApp({
        el: '#el',
+
         data: () => ({
         data: {
+
             mensaje: "",
 
+
         }),
             mensaje: " ",
 
 
 
            profesores: [{
 
                    nombre: "Julio Noguera",
 
                    activo: true
 
                },
 
                {
 
                    nombre: "Albert Canela",
 
                    activo: true
 
                },
 
                {
 
                    nombre: "Alex Salinas",
 
                    activo: false
 
                }
 
 
 
            ]
 
         },
 
 
         methods: {
 
         methods: {
             invertir: function () {
+
             invertir() {
                 this.mensaje = this.mensaje.split('').reverse('').join(''); //utilizamos this.mensaje para acceder a los datos
+
                 this.mensaje = this.mensaje.split('').reverse().join('');
 
             }
 
             }
 
         }
 
         }
     })
+
     }).mount("#el");
 
</script>
 
</script>
 
</source>
 
</source>
Línia 282: Línia 250:
 
Mostrar lista asociando evento click
 
Mostrar lista asociando evento click
 
<source lang="javascript">
 
<source lang="javascript">
 +
<style>
 +
.false{background:blue}
 +
.true{background: green}
 +
</style>
 
<body>
 
<body>
 
     <div class="container">
 
     <div class="container">
         <div id="elemento">
+
         <div id="el">
 
             <ul>
 
             <ul>
 
                 <li v-for="profe in profesores">
 
                 <li v-for="profe in profesores">
 
                     <span v-text="profe.nombre"></span>
 
                     <span v-text="profe.nombre"></span>
                     <span @click="profe.activo=false" v-if="profe.activo" class="glyphicon glyphicon-check"></span>
+
                     <span @click="profe.activo=false" v-if="profe.activo" class="false">X</span>
                     <span @click="profe.activo=true" v-else class="glyphicon glyphicon-unchecked"></span>
+
                     <span @click="profe.activo=true" v-else class="true">X</span>
  
 
                 </li>
 
                 </li>
 
             </ul>
 
             </ul>
             <pre>
+
             <pre>{{$data}}</pre>
                    {{$data}}
 
            </pre>
 
 
 
 
 
 
         </div>
 
         </div>
 
     </div>
 
     </div>
Línia 304: Línia 272:
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
     var variable = new Vue({
+
     var variable = Vue.createApp({
        el: '#elemento',
+
         data: () => ({
         data: {
 
 
 
            profe: "",
 
 
 
 
             profesores: [{
 
             profesores: [{
 
                     nombre: "Julio Noguera",
 
                     nombre: "Julio Noguera",
Línia 325: Línia 289:
 
             ]
 
             ]
  
         }
+
         })
     })
+
     }).mount("#el");
 
</script>
 
</script>
 
</source>
 
</source>
Línia 340: Línia 304:
 
<body>
 
<body>
 
     <div id="el">
 
     <div id="el">
 
 
 
         <ul>
 
         <ul>
            <!-- <li v-text="profesores[0]"></li>-->
 
 
             <li v-for="profesor in profesores">
 
             <li v-for="profesor in profesores">
 
                 <span v-text="profesor.nombre"></span>
 
                 <span v-text="profesor.nombre"></span>
Línia 349: Línia 310:
 
                 <small v-else>-NO está</small>
 
                 <small v-else>-NO está</small>
 
             </li>
 
             </li>
 +
          <input v-on:keyup.enter="anadir" type="text" v-model="profe" >
  
            <input v-on:keyup.13="anadir" type="text" v-model="profe" >  <!-- cuando apretamos el ENTER hace el evento (el 13 es enter en ascii)-->
+
            <!-- <input @keyup.enter="anadir" type="text" v-model="profe" > -->
            <!-- <input v-on:keyup.enter="anadir" type="text" v-model="profe" >  -->
 
          <!-- <input type="text" v-model="profe"> -->
 
          <!-- <button @click="anadir">+ añadir</button>-->
 
 
         </ul>
 
         </ul>
 
     </div>
 
     </div>
</body>
 
  
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
+
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
+
    <script>
    var variable = new Vue({
+
        var variable = Vue.createApp({
        el: '#el',
+
            data:() => ({
        data: {
+
              profe: "",
 
+
                profesores: [
            profe: "",
+
                  { nombre: "Julio Noguera", activo: true },
 
+
                  { nombre: "Albert Canela", activo: true },
            profesores: [{
+
                  { nombre: "Alex Salinas", activo: false }
                    nombre: "Julio Noguera",
+
                 ]
                    activo: true
+
            }),
                },
+
            methods: {
                {
+
                 anadir() {
                    nombre: "Albert Canela",
+
                     this.profesores.push({
                    activo: true
+
                        nombre: this.profe,
                 },
+
                        activo: false
                 {
+
                    });
                     nombre: "Alex Salinas",
+
                    this.profe = ""; // Restableix el valor de profe a una cadena buida després d'afegir-lo
                    activo: false
 
 
                 }
 
                 }
 
            ]
 
        },
 
        methods: {
 
            anadir: function () {
 
 
                this.profesores.push({
 
                    nombre: this.profe,
 
                    activo: false
 
                });
 
 
 
             }
 
             }
         }
+
         }).mount("#el");
     })
+
     </script>
</script>
+
</body>
 
</source>
 
</source>
 
 
 
DIRECTIVA COMPUTED.
 
  
 
=== DIRECTIVA V-BIND===  
 
=== DIRECTIVA V-BIND===  
Línia 404: Línia 346:
  
 
<source lang="javascript">
 
<source lang="javascript">
 +
<style>
 +
    .rojo {
 +
        background: red;
 +
    }
 +
 +
    .verde {
 +
        background: green;
 +
    }
 +
    .glyphicon{
 +
        color: white;
 +
    }
 +
</style>
 
<body>
 
<body>
  <div class="container">
+
 
       <div id="elemento">
+
       <div id="el">
 
           <ul>
 
           <ul>
 
+
            <!--//en el caso de querer añadir varias clases-->
<!--v-bind:class="['glyphicon',tarea.completo ? 'glyphicon-check': 'glyphicon-unchecked']" //en el caso de querer añadir varias clases-->
+
            <!-- v-bind:class="['glyphicon',tarea.completo ? 'verde': 'rojo']" -->
 
 
 
               <li v-for="tarea in tareas">  
 
               <li v-for="tarea in tareas">  
                   <span v-text="tarea.nombre" @click="tarea.completo=!tarea.completo" ></span>
+
                   <span v-bind:class="{ 
 +
                              'rojo': !tarea.completo,
 +
                              'verde': tarea.completo
 +
                                }" v-text="tarea.nombre" @click="tarea.completo=!tarea.completo" ></span>
 
                   <input type="checkbox"  v-model="tarea.completo">
 
                   <input type="checkbox"  v-model="tarea.completo">
                <span v-bind:class="{ 
 
                              'glyphicon': true, 
 
                              'glyphicon-check':tarea.completo,
 
                              'glyphicon-unchecked': ! tarea.completo
 
                                }"></span>
 
 
               </li>
 
               </li>
 
           </ul>
 
           </ul>
 
           <pre>
 
           <pre>
                  {{$data}}
+
            {{$data}}
             
 
 
           </pre>
 
           </pre>
 
       </div>
 
       </div>
  </div>
+
 
 
</body>
 
</body>
  
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
   var variable = new Vue({
+
   var variable = Vue.createApp({
      el: '#elemento',
+
       data: () => ({
       data: {
+
           tareas: [
 
+
            {
           tareas: [{
+
                nombre: "Estudiar",
              nombre: "Estudiar",
+
                completo: true
              completo: true
+
            },
          },
+
            {
          {
+
                nombre: "Repasar",
              nombre: "Repasar",
+
                completo: true
              completo: true
+
            },
          },
+
            {
          {
+
                nombre: "Examinar",
              nombre: "Examinar",
+
                completo: false
              completo: false
+
            }
          }
 
 
 
 
           ]
 
           ]
 
+
       })
       }
+
   }).mount("#el");
   })
 
</script>
 
 
</script>
 
</script>
 
</source>
 
</source>
Línia 462: Línia 408:
 
Como se puede ver, se produce un incremento de voto modificando su atributo directamente.  
 
Como se puede ver, se produce un incremento de voto modificando su atributo directamente.  
 
<source lang="javascript">
 
<source lang="javascript">
 
 
<body>
 
<body>
 
     <div class="container">
 
     <div class="container">
Línia 468: Línia 413:
 
         <div>
 
         <div>
 
             <ul>
 
             <ul>
              <li v-for="storie in stories"><button  @click="storie.votos++">Vote</button><pre v-text="storie.votos"></pre></li>
+
                <li v-for="storie in stories">
 +
                    <button  @click="storie.votos++">Vote {{storie.politico}}</button>
 +
                    <!-- <button  @click="incrementVote(storie)">Vote {{storie.politico}}</button> -->
 +
                    <pre v-text="storie.votos"></pre>
 +
                </li>
 
             </ul>
 
             </ul>
 
         </div>
 
         </div>
         <pre>
+
         <pre>{{$data}}</pre>
{{$data | json}}
 
</pre>
 
 
     </div>
 
     </div>
 
</body>
 
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.js"></script>
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script type="text/javascript">
 
<script type="text/javascript">
    new Vue({
+
  const app = Vue.createApp({
        el: '.container',
+
    data() {
        data: {
+
      return {
            stories: [{
+
        stories: [
                    politico: "julio",
+
          { politico: "julio", votos: 1 },
                    votos: 1
+
          { politico: "paco", votos: 2 },
                },
+
          { politico: "raúl", votos: 3 },
                {
+
          { politico: "jorge", votos: 4 }
                    politico: "paco",
+
        ]
                    votos: 2
+
      };
                },
+
    },
                {
+
    methods: {
                    politico: "raúl",
+
      incrementVote(storie) {
                    votos: 3
+
         storie.votos++;
                },
+
      }
                {
+
     }
                    politico: "jorge",
+
  }).mount(".container");
                    votos: 4
 
                },
 
            ]
 
         }      
 
     })
 
</source>
 
  
 
+
</script>
===Ejercicio===
 
<!--
 
Se desea mostrar una lista de tareas, se pide que se pueda eliminar el item seleccionado.
 
 
 
'''Solución''':
 
 
 
<source lang="js">
 
<body>
 
    <div id="el">
 
        <div v-for="tarea in tareas" >
 
            <div v-text="tarea" ></div> <span @click="eliminar(tarea)">X</span>
 
        </div>
 
        <input type="text" v-model="tarea"><span @click="anadir">+</span>
 
        <br>
 
        {{$data}}
 
 
 
    </div>
 
 
 
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
    Vue.config.devtools = true
 
    var variable = new Vue({
 
        el: '#el',
 
        data: {
 
 
 
            tarea: "",
 
 
 
            tareas: []
 
        },
 
        methods: {
 
            anadir: function(){
 
                this.tareas.push(this.tarea);
 
                console.log(this.tareas);
 
            },
 
            eliminar: function(tarea){
 
                let x=this.tareas.indexOf(tarea);
 
                this.tareas.splice(x, 1);
 
            }
 
           
 
        }
 
    });
 
    </script>
 
</body>
 
 
 
</html>
 
 
</source>
 
</source>
 
-->
 
 
 
https://www.youtube.com/watch?v=jfEEQVdbl54&list=PLPl81lqbj-4J-gfAERGDCdOQtVgRhSvIT&index=7&t=0s
 
  
 
=== FILTRAR ===
 
=== FILTRAR ===
Línia 576: Línia 467:
 
   <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
   <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
   <script>
 
   <script>
    Vue.config.devtools = true;
+
     var app = Vue.createApp({
     var app = new Vue({
+
       data:() => ({
      el: '#aplicacion',
 
       data: {
 
  
 
         minimo: "5",
 
         minimo: "5",
Línia 598: Línia 487:
 
           precio: 18.20
 
           precio: 18.20
 
         }]
 
         }]
       },
+
       }),
 
       computed: {
 
       computed: {
 
         filtrar() {
 
         filtrar() {
Línia 608: Línia 497:
  
 
       }
 
       }
     })
+
     }).mount("#aplicacion")
 +
 
 
   </script>
 
   </script>
 
</source>
 
</source>
Línia 614: Línia 504:
 
==Componentes==
 
==Componentes==
  
1. Crear una nueva instancia de Vue con new Vue
+
1. Crear una nueva instancia de Vue con Vue.createApp
  
 
2. Existen 3 Objetos básicos y fundamentales que estarán en la mayoria de las aplicaciones web: el data y methods.
 
2. Existen 3 Objetos básicos y fundamentales que estarán en la mayoria de las aplicaciones web: el data y methods.
Línia 627: Línia 517:
 
   <div id="aplicacion">
 
   <div id="aplicacion">
 
     <!-- vue está disponible en todo este div-->
 
     <!-- vue está disponible en todo este div-->
 +
    <hola-mundo></hola-mundo>
 
   </div>
 
   </div>
 
   
 
   
Línia 632: Línia 523:
  
 
<script>
 
<script>
  Vue.component('hola-mundo', {    //debe coincidir con el nombre del componente(etiqueta html)
+
    template: `<p>
 
                Hola mundo
 
              </p>`
 
  });
 
  
//nueva instacia de Vue : new Vue
+
//nueva instacia de Vue : Vue.createApp
   var app=new Vue({
+
   var app= Vue.createApp({
     el: '#aplicacion',  // el elemento donde se aplicará Vue, en este caso un div con id = main
+
     data:() => ({ //capa de datos
    data:{ //capa de datos
 
  
     },
+
     }),
 
     methods:
 
     methods:
 
     {
 
     {
  
 
     }
 
     }
     });
+
     })
 +
   
 +
    app.component('hola-mundo', {    //debe coincidir con el nombre del componente(etiqueta html)
 +
    template: `<p>
 +
                Hola mundo
 +
              </p>`
 +
  });
 +
   
 +
    app.mount('#aplicacion')  // el elemento donde se aplicará Vue, en este caso un div con id = main);
 
</script>
 
</script>
 
</source>
 
</source>
Línia 667: Línia 561:
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
   Vue.component('hola-mundo', {
+
    
 +
  var app= Vue.createApp({
 +
  })
 +
 
 +
  app.component('hola-mundo', {
 
     props: ['idioma'],
 
     props: ['idioma'],
 
     template: `<div>
 
     template: `<div>
Línia 674: Línia 572:
 
               </div>`
 
               </div>`
 
   })
 
   })
 
+
 
   var app=new Vue({
+
   app.mount("#aplicacion")
    el: '#aplicacion'
 
  })
 
 
</script>
 
</script>
  
Línia 686: Línia 582:
  
 
<source lang="javascript">
 
<source lang="javascript">
<div id="app">
+
<body>
 +
 +
<div id="app">
 
  <ejemplo nombre="Juan" apellido="Perez"></ejemplo>  
 
  <ejemplo nombre="Juan" apellido="Perez"></ejemplo>  
 
  <ejemplo nombre="Alejandra" apellido="Quiroga"></ejemplo>  
 
  <ejemplo nombre="Alejandra" apellido="Quiroga"></ejemplo>  
 
</div>
 
</div>
  
Vue.component('ejemplo', {
+
 
props: ['nombre', 'apellido'],
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
template: '<p> Hola {{nombre}} {{apellido}} </p>'  
+
<script>
});
+
 
 +
  var app= Vue.createApp({
 +
  })
 +
 
 +
 
 +
  app.component('ejemplo', {
 +
  props: ['nombre', 'apellido'],
 +
  template: '<p> Hola {{nombre}} {{apellido}} </p>'  
 +
  });
 +
 
 +
  app.mount("#app")
 +
</script>
 +
 
 +
</body>
 
</source>
 
</source>
  
Línia 702: Línia 613:
 
   <div class="container">
 
   <div class="container">
 
     <peliculas titulo="peliculon 1917"
 
     <peliculas titulo="peliculon 1917"
       imagen="https://pbs.twimg.com/profile_banners/1207170793177640960/1576648504/1080x360"></peliculas>
+
       imagen="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcSexz8IyOhoxR2ibVc78RHzpBCsvhDt3fx0wl99Qcxacht4gk9z"></peliculas>
 
   </div>
 
   </div>
</body>
 
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.js">
+
 
</script>
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script type="text/javascript">
 
<script type="text/javascript">
   Vue.config.devtools = true;
+
    
  
   Vue.component('peliculas', {
+
   var app = Vue.createApp({
 +
 
 +
  })
 +
 
 +
  app.component('peliculas', {
  
 
     props: ['imagen', 'titulo'],  //los props reciben los datos externos del html en este caso será "peliculon 1917" y la ruta de la imagen
 
     props: ['imagen', 'titulo'],  //los props reciben los datos externos del html en este caso será "peliculon 1917" y la ruta de la imagen
Línia 720: Línia 634:
 
       </div>`
 
       </div>`
 
   });
 
   });
 +
 
 +
  app.mount(".container")
  
 
  new Vue({
 
    el: '.container'
 
  })
 
 
</script>
 
</script>
 +
</body>
 
</source>
 
</source>
  
Línia 734: Línia 647:
 
<body>
 
<body>
 
   <div class="container">
 
   <div class="container">
     <div v-for="(index, dato) in datos">  <!--añadimos indice-->
+
     <div v-for="(dato, index) in datos">  <!-- Corregido -->
 
       <peliculas :key="index" :titulo="dato.titulo" :imagen="dato.imagen">
 
       <peliculas :key="index" :titulo="dato.titulo" :imagen="dato.imagen">
 
       </peliculas>
 
       </peliculas>
 
     </div>
 
     </div>
 
   </div>
 
   </div>
 +
 +
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 +
 +
  <script type="text/javascript">
 +
var app = Vue.createApp({
 +
      data: () => ({
 +
          datos: [{
 +
              titulo: "star wars",
 +
              imagen: "https://vignette.wikia.nocookie.net/cine/images/8/88/Sw1.jpg/revision/latest?cb=20120930202439 "
 +
            },
 +
            {
 +
              titulo: "Sonic",
 +
              imagen: "https://www.smashbros.com/wiiu-3ds/images/character/sonic/main.png"
 +
            },
 +
            {
 +
              titulo: "Mario bros",
 +
              imagen: "https://imagenesparapeques.com/wp-content/uploads/2021/05/Mario-Bros-png-transparente.png"
 +
            }
 +
          ]
 +
 +
        })
 +
    })
 +
 +
    app.component('peliculas', {
 +
    props: ['titulo', 'imagen'],
 +
      template: `<div>
 +
        <img width="100px" :src="imagen" :alt="titulo"/>
 +
        <h2>{{ titulo }}</h2>
 +
      </div>`
 +
    });
 +
   
 +
app.mount(".container")
 +
 +
  </script>
 
</body>
 
</body>
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.js">
+
</source>
</script>
+
 
<script type="text/javascript">
+
 
  Vue.config.devtools = true;
+
'''Componentes: definición de métodos y modelo de datos'''
 +
 
  
  Vue.component('peliculas', {
 
    props: ['key','titulo', 'imagen'],
 
    template: `<div>
 
      <img width="100px" v-bind:src="imagen" v-bind:alt="titulo"/>
 
      <h2> {{titulo}}: {{key}} </h2>
 
      </div>`
 
  });
 
  
 +
<source lang="javascript">
 +
<body>
 +
  <div id="el" class="container">
 +
    <h1> Helados </h1>
 +
    <h2> Lista </h2>
 +
    <ul>
 +
      <li v-for="item in helados" :key="item.sabor">
 +
        <component-helado v-bind:helado="item"></component-helado>
 +
      </li>
 +
    </ul>
 +
    <h2> Seleccionados </h2>
 +
    <ul>
 +
      <li v-for="item in heladosSeleccionados" :key="item.sabor"> {{ item.sabor }} </li>
 +
    </ul>
 +
  </div>
 +
</body>
  
  new Vue({
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
    el: '.container',
+
<script type="text/javascript">
    data: {
+
    var app = Vue.createApp({
      datos: [{
+
      data: () => ({
           titulo: "star wars",
+
        helados: [{
           imagen: "https://vignette.wikia.nocookie.net/cine/images/8/88/Sw1.jpg/revision/latest?cb=20120930202439 "
+
            sabor: 'Chocolate',
         },
+
            seleccionado: false
         {
+
          },
           titulo: "Sonic",
+
          {
           imagen: "https://www.smashbros.com/wiiu-3ds/images/character/sonic/main.png"
+
            sabor: 'Dulce de leche',
 +
            seleccionado: false
 +
          },
 +
          {
 +
            sabor: 'Frutilla',
 +
            seleccionado: false
 +
          },
 +
           {
 +
            sabor: 'Limón',
 +
            seleccionado: false
 +
          },
 +
           {
 +
            sabor: 'Vainilla',
 +
            seleccionado: false
 +
          }
 +
        ]
 +
      }),
 +
      computed: {
 +
        heladosSeleccionados() {
 +
          return this.helados.filter(helado => helado.seleccionado);
 +
         }
 +
      }
 +
    });
 +
 
 +
    app.component('component-helado', {
 +
      props: ['helado'],
 +
      template: `
 +
         <div>
 +
           <button class="btn btn-success" v-on:click="agregar(helado)" v-if="!helado.seleccionado"> + </button>
 +
           <button class="btn btn-danger" v-on:click="eliminar(helado)" v-if="helado.seleccionado"> - </button>
 +
          <span> {{ helado.sabor }} </span>
 +
          <hr/
 +
        </div>  `,
 +
      methods: {
 +
        agregar(helado) {
 +
          helado.seleccionado = true;
 
         },
 
         },
         {
+
         eliminar(helado) {
           titulo: "Mario bros",
+
           helado.seleccionado = false;
          imagen: "https://cdn02.nintendo-europe.com/media/images/05_packshots/games_13/nes_1/PS_NES_SuperMarioBros.jpg"
 
 
         }
 
         }
       ]
+
       }
 
+
     });
     }
 
  })
 
  
 +
    app.mount('#el');
 
</script>
 
</script>
 
 
</source>
 
</source>
  
 
+
== Ejercicios ==
==Ejercicios ==
 
  
 
'''v-if, v-else, v-else-if, v-show'''
 
'''v-if, v-else, v-else-if, v-show'''
  
Tenemos dos inputs de tipo passwords y muestre un mensaje en caso que sean iguales
+
Crear dos inputs de tipo password y mostrar un mensaje en caso de que sean iguales
  
 
'''solución:'''
 
'''solución:'''
Línia 801: Línia 789:
 
   </div>
 
   </div>
  
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>  
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
   <script>
 
   <script>
     var app=new Vue({
+
     var app = Vue.createApp({
      el: '#aplicacion',
+
       data:() => ({  
       data:{  
 
 
         clave1 : '',
 
         clave1 : '',
 
         clave2 : ''
 
         clave2 : ''
       }
+
       })
     })
+
     }).mount("#aplicacion")
 
   </script>
 
   </script>
 
</body>
 
</body>
 
</source>
 
</source>
 +
  
 
'''v-for'''
 
'''v-for'''
  
Tenemos un array en data con los días de la semana, se trata de generar una tabla de 1 columna y 7 filas en HTML
+
Crear un array en data con los días de la semana y generar una tabla de 1 columna y 7 filas en HTML
  
 
'''solución:'''
 
'''solución:'''
Línia 830: Línia 818:
 
   </div>
 
   </div>
  
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>  
+
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
   <script>
 
   <script>
     var app=new Vue({
+
     var app= Vue.createApp({
      el: '#aplicacion',
+
       data:() => ({  
       data:{  
 
 
         dias: ['lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado', 'domingo']
 
         dias: ['lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado', 'domingo']
       }
+
       })
     })
+
     }).mount("#aplicacion")
 
   </script>
 
   </script>
 +
</body>
 
</source>
 
</source>
  
Línia 863: Línia 851:
  
 
'''solución:'''
 
'''solución:'''
 +
 
<source lang="javascript">
 
<source lang="javascript">
  
Línia 880: Línia 869:
 
   <script src="https://cdn.jsdelivr.net/npm/vue"></script>   
 
   <script src="https://cdn.jsdelivr.net/npm/vue"></script>   
 
   <script>
 
   <script>
     var app=new Vue({
+
     var app= Vue.createApp({
      el: '#aplicacion',
+
       data:() => ({  
       data:{  
 
 
         personas: [{
 
         personas: [{
 
                     nombre: 'Jose',  
 
                     nombre: 'Jose',  
Línia 897: Línia 885:
 
                   }]
 
                   }]
  
       }
+
       })
     })
+
     }).mount("#aplicacion")
 
   </script>
 
   </script>
 
</body>
 
</body>
 
</source>
 
</source>
  
 +
<!--
 
===Ejercicios===
 
===Ejercicios===
  
Línia 912: Línia 901:
 
     <div id="el">  
 
     <div id="el">  
 
         <div v-for="profesor in profesores" >
 
         <div v-for="profesor in profesores" >
             <div v-text="profesor.nombre" ></div> <div v-text="profesor.edad"></div><span @click="incrementar(profesor)">+</span>
+
             <div v-text="profesor.nombre" ></div> <div v-text="profesor.edad"></div>
 +
            <button @click="incrementar(profesor)">+</span>
 
         </div>
 
         </div>
         <input type="text" v-model="profesor" @click="anadir">
+
         <input type="text" v-model="profesor"><button @click="anadir">Añadir</button>
 
         <br>
 
         <br>
 
         {{$data}}
 
         {{$data}}
Línia 922: Línia 912:
 
     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
     <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
    Vue.config.devtools = true
+
     var variable = Vue.createApp({
     var variable = new Vue({
+
         data: () => ({
        el: '#el',
 
         data: {
 
  
 
             profesor: " ",
 
             profesor: " ",
Línia 943: Línia 931:
  
 
             ]
 
             ]
         },
+
         }),
 
         methods: {
 
         methods: {
 
             anadir: function(){
 
             anadir: function(){
Línia 953: Línia 941:
 
             }
 
             }
 
         }
 
         }
     });
+
     }).mount("#el");
 
     </script>
 
     </script>
 
</source>
 
</source>
 +
  
  
Línia 982: Línia 971:
 
   <script src="https://cdn.jsdelivr.net/npm/vue"></script>   
 
   <script src="https://cdn.jsdelivr.net/npm/vue"></script>   
 
   <script>
 
   <script>
     var app=new Vue({
+
     var app= Vue.createApp({
      el: '#aplicacion',
+
       data: () => ({  
       data:{  
 
 
         valor1: 0,
 
         valor1: 0,
 
         valor2: 0,
 
         valor2: 0,
 
         suma: ''
 
         suma: ''
       },
+
       }),
 
       methods: {
 
       methods: {
 
         sumarValores: function() {
 
         sumarValores: function() {
Línia 994: Línia 982:
 
         }
 
         }
 
       }       
 
       }       
     })
+
     }).mount("#aplicacion")
 
   </script>
 
   </script>
 
</source>
 
</source>
  
'''Eventos: v-on:keypress, v-on:keyup'''
+
===Ejercicio===
 +
-->
  
Mediante un control de tipo input permitir el ingreso de una frase. Mostrar por pantalla cada vez que presionamos una tecla la cantidad de letras 'a' que tiene la
+
'''methods'''
oración.
 
  
'''solución:'''
+
Se desea mostrar una lista de tareas, se pide que se pueda eliminar el item seleccionado.
 +
 
 +
'''Solución''':
  
 
<source lang="javascript">
 
<source lang="javascript">
 
<body>
 
<body>
  <div id="aplicacion">
+
    <div id="el">  
    <p>Ingrese una frase:
+
        <div v-for="tarea in tareas" >   <div v-for="(item, index) in tareas" >
      <input v-model="frase" v-on:keyup="contabilizarLetrasA" type="text" size="80">
+
            <div v-text="tarea" ></div> <span @click="eliminar(tarea)">X</span>
    </p>
+
        </div>
    <p>Cantidad de letras 'a o 'A'':{{cantidadLetrasa}}</p>
+
        <input type="text" v-model="tarea">
  </div>
+
        <button @click="anadir">+</button>
 +
       
 +
        <br>
 +
        {{$data}}
 +
 
 +
    </div>
  
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
+
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script>
+
    <script>
    var app=new Vue({
+
        var variable = Vue.createApp({
      el: '#aplicacion',
+
            data() {
      data:{  
+
                return {
        cantidadLetrasa: 0,
+
                    tarea: "",
        frase: ''
+
                    tareas: []
      },
+
                }
      methods: {
+
            },
        contabilizarLetrasA: function () {
+
            methods: {
          var cant=0;
+
                anadir() {
          for(var f=0; f<this.frase.length; f++)
+
                    this.tareas.push(this.tarea);
            if (this.frase[f]=='a' || this.frase[f]=='A')
+
                    console.log(this.tareas);
              cant++;
+
                },
          this.cantidadLetrasa=cant;
+
                eliminar(tarea) {
        }
+
                    let index = this.tareas.indexOf(tarea);
      }
+
                    if (index !== -1) {
    })
+
                        this.tareas.splice(index, 1);
  </script>
+
                    }
 +
                }
 +
            }
 +
        }).mount('#el');
 +
    </script>
 
</body>
 
</body>
  
 +
</html>
 
</source>
 
</source>
  
Línia 1.042: Línia 1.042:
 
Tenemos un input de tipo text que introducimos un texto, a medida que vayamos escribiendo texto deberá ir mostrando la cantidad de 'a' y 'A' que hay
 
Tenemos un input de tipo text que introducimos un texto, a medida que vayamos escribiendo texto deberá ir mostrando la cantidad de 'a' y 'A' que hay
  
 +
<!--
 
'''solución:'''
 
'''solución:'''
  
 
<source lang="javascript">
 
<source lang="javascript">
 
<body>
 
<body>
  <div id="aplicacion">
+
    <div id="aplicacion">
    <p>Ingrese una frase:
+
      <p>Ingrese una frase:
      <input v-model="frase" v-on:keyup="contabilizarLetrasA" type="text" size="80">
+
        <input v-model="frase" v-on:keyup="contabilizarLetrasA" type="text" size="80">
    </p>
+
      </p>
    <p>Cantidad de letras 'a o 'A'':{{cantidadLetrasa}}</p>
+
      <p>Cantidad de letras 'a o 'A'':{{cantidadLetrasa}}</p>
   </div>
+
    </div>
 +
    
 +
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 +
    <script>
 +
      var app = Vue.createApp({
 +
        data:() => ({
 +
          cantidadLetrasa: 0,
 +
          frase: ''
 +
        }),
 +
        methods: {
 +
          contabilizarLetrasA:  function() {
 +
            var cant=0;
 +
            for(var f=0; f<this.frase.length; f++)
 +
              if (this.frase[f]=='a' || this.frase[f]=='A')
 +
                cant++;
 +
            this.cantidadLetrasa=cant;
 +
          }
 +
        }
 +
      }).mount('#aplicacion');
 +
    </script>
 +
  </source>
  
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
  <script>
 
    var app=new Vue({
 
      el: '#aplicacion',
 
      data:{
 
        cantidadLetrasa: 0,
 
        frase: ''
 
      },
 
      methods: {
 
        contabilizarLetrasA: function () {
 
          var cant=0;
 
          for(var f=0; f<this.frase.length; f++)
 
            if (this.frase[f]=='a' || this.frase[f]=='A')
 
              cant++;
 
          this.cantidadLetrasa=cant;
 
        }
 
      }
 
    })
 
  </script>
 
</source>
 
  
 
'''bind (enlace) a clases CSS'''
 
'''bind (enlace) a clases CSS'''
Línia 1.121: Línia 1.122:
  
 
'''solución:'''  
 
'''solución:'''  
 +
 
<source lang="javascript">
 
<source lang="javascript">
 
<body>
 
<body>
 +
  <style>
 +
    .tachar {
 +
      text-decoration: line-through;
 +
      color: blue;
 +
    }
 +
  </style>
 
   <div id="aplicacion">
 
   <div id="aplicacion">
 
     <ul style="font-size:2rem; list-style:none">
 
     <ul style="font-size:2rem; list-style:none">
 
       <li v-for="lenguaje in lenguajes"
 
       <li v-for="lenguaje in lenguajes"
           v-on:click="presion(lenguaje)"
+
           @click="presion(lenguaje)"
 
           v-bind:class="{tachar: lenguaje.tachado }">
 
           v-bind:class="{tachar: lenguaje.tachado }">
 
         {{lenguaje.nombre}}
 
         {{lenguaje.nombre}}
Línia 1.135: Línia 1.143:
 
   <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
   <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
   <script>
 
   <script>
var app=new Vue({
+
var app= Vue.createApp({
      el: '#aplicacion',
+
       data: () => ({  
       data:{  
 
 
         lenguajes: [
 
         lenguajes: [
 
           {
 
           {
Línia 1.167: Línia 1.174:
 
             tachado:false
 
             tachado:false
 
           }]         
 
           }]         
       },
+
       }),
 
       methods: {
 
       methods: {
 
         presion: function(lenguaje) {
 
         presion: function(lenguaje) {
           lenguaje.tachado=true;
+
           lenguaje.tachado= !lenguaje.tachado;
 
         }
 
         }
 
       }
 
       }
     })
+
     }).mount('#aplicacion');
 
   </script>
 
   </script>
 
</body>
 
</body>
 
</source>
 
</source>
 +
-->
  
 
'''Componentes en Vue'''
 
'''Componentes en Vue'''
Línia 1.182: Línia 1.190:
 
Crear una componente llamada 'acerca-de' que muestre el nombre del programa y la versión del mismo.
 
Crear una componente llamada 'acerca-de' que muestre el nombre del programa y la versión del mismo.
  
 +
<!--
 
'''Solución:'''
 
'''Solución:'''
  
Línia 1.192: Línia 1.201:
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
   Vue.component('acerca-de', {
+
 
    template: `<div><p>Programa: xxxxxxxx</p>
+
   var app = Vue.createApp({
                    <p>Versión: xx</p></div> `
 
 
   })
 
   })
  
   new Vue({
+
   app.component('acerca-de', {
     el: '#aplicacion'
+
     data: () => ({
 +
      navigator: navigator.appCodeName || 'Unknown',
 +
      version: navigator.appVersion
 +
    }),
 +
    template: `<div><p>Programa: {{navigator}}</p>
 +
                    <p>Versión: {{version}}</p></div> `
 
   })
 
   })
 +
 +
  app.mount('#aplicacion')
 
</script>
 
</script>
  
 
</body>
 
</body>
 
</source>
 
</source>
 +
  
 
'''Componentes: propiedades'''
 
'''Componentes: propiedades'''
Línia 1.220: Línia 1.236:
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
   Vue.component('hola-mundo', {
+
 
 +
 
 +
   var app = Vue.createApp({
 +
    data: () => ({
 +
      idioma: 'castellano'
 +
    })
 +
  })
 +
 
 +
  app.component('hola-mundo', {
 
     props: ['idioma'],
 
     props: ['idioma'],
 
     template: `<div>
 
     template: `<div>
Línia 1.228: Línia 1.252:
 
   })
 
   })
  
   var app=new Vue({
+
   app.mount('#aplicacion');
    el: '#aplicacion',
 
    data: {
 
      idioma: 'castellano'
 
    }
 
  })
 
 
</script>
 
</script>
  
Línia 1.255: Línia 1.274:
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
 
<script>
 
<script>
   Vue.component('articulos', {
+
    
 +
  var app= Vue.createApp({
 +
    data: () => ({
 +
      datos: [{
 +
          codigo: 1,
 +
          descripcion: 'papas',
 +
          precio: 12.52
 +
        },{
 +
          codigo: 2,
 +
          descripcion: 'naranjas',
 +
          precio: 21
 +
        },{
 +
          codigo: 3,
 +
          descripcion: 'peras',
 +
          precio: 18.20
 +
        }]     
 +
    })
 +
  })
 +
 
 +
  app.component('articulos', {
 
     props:['datos'],
 
     props:['datos'],
 
     template: `<div>
 
     template: `<div>
Línia 1.265: Línia 1.303:
 
   })
 
   })
  
   var app=new Vue({
+
 
    el: '#aplicacion',
+
   app.mount('#aplicacion');
    data: {
 
      datos: [{
 
              codigo: 1,
 
              descripcion: 'papas',
 
              precio: 12.52
 
              },{
 
              codigo: 2,
 
              descripcion: 'naranjas',
 
              precio: 21
 
              },{
 
              codigo: 3,
 
              descripcion: 'peras',
 
              precio: 18.20
 
              }]     
 
    }
 
  })
 
 
</script>
 
</script>
  
 
</body>
 
</body>
 
</source>
 
</source>
 
  
  
Línia 1.295: Línia 1.316:
  
 
'''Solución:'''
 
'''Solución:'''
 +
 
<source lang="javascript">
 
<source lang="javascript">
 
<body>
 
<body>
Línia 1.304: Línia 1.326:
 
<script>
 
<script>
 
    
 
    
   Vue.component('contador', {
+
 +
   var app= Vue.createApp({
 +
  })
 +
 
 +
  app.component('contador', {
 
     template:`<div><button v-on:click="incrementar()">
 
     template:`<div><button v-on:click="incrementar()">
 
               {{cantidad}}
 
               {{cantidad}}
 
               </button></div>`,
 
               </button></div>`,
     data: function() {
+
     data: () => ({
       return {
+
       cantidad: 0
        cantidad: 0
+
     }),
      }
 
     },
 
 
     methods: {
 
     methods: {
 
       incrementar: function() {
 
       incrementar: function() {
Línia 1.320: Línia 1.344:
 
   });
 
   });
  
   var app=new Vue({
+
   app.mount('#aplicacion');
    el: '#aplicacion'
 
  })
 
  
</script>
 
</body>
 
</source>
 
 
 
'''Componentes: definición de métodos y modelo de datos'''
 
 
 
 
<source lang="javascript">
 
<body>
 
  <div id="app" class="container">
 
    <h1> Helados </h1>
 
    <h2> Lista </h2>
 
    <ul>
 
      <li v-for="item in helados">
 
        <component-helado v-bind:helado="item"></component-helado>
 
      </li>
 
    </ul>
 
    <h2> Seleccionados </h2>
 
    <ul>
 
      <li v-for="item in helados" v-if="item.seleccionado"> {{ item.sabor }} </li>
 
    </ul>
 
  </div>
 
</body>
 
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.js">
 
 
</script>
 
</script>
<script type="text/javascript">
 
  Vue.config.devtools = true;
 
    Vue.component('component-helado', {
 
      props: ['helado'],
 
      template: `
 
    <div>
 
      <button class="btn btn-success" v-on:click="agregar(helado)" v-if="!helado.seleccionado"> + </button>
 
      <button class="btn btn-danger" v-on:click="eliminar(helado)" v-if="helado.seleccionado"> - </button>
 
      <span> {{ helado.sabor }} </span>
 
      <hr/>  </div>  `,
 
      methods: {
 
        agregar: function (p_helado) {
 
          p_helado.seleccionado = true;
 
        },
 
        eliminar: function (p_helado) {
 
          p_helado.seleccionado = false;
 
        }
 
      }
 
    });
 
 
    new Vue({
 
      el: '#app',
 
      data: {
 
        helados: [{
 
            sabor: 'Chocolate',
 
            seleccionado: false
 
          },
 
          {
 
            sabor: 'Dulce de leche',
 
            seleccionado: false
 
          },
 
          {
 
            sabor: 'Frutilla',
 
            seleccionado: false
 
          },
 
          {
 
            sabor: 'Limón',
 
            seleccionado: false
 
          },
 
          {
 
            sabor: 'Vainilla',
 
            seleccionado: false
 
          }
 
        ]
 
      }
 
    });
 
</script>
 
 
 
</body>
 
</body>
 
 
</source>
 
</source>
  
 +
-->
  
 +
https://www.tutorialesprogramacionya.com/vueya/
  
<source lang="javascript">
+
https://www.youtube.com/watch?v=jfEEQVdbl54&list=PLPl81lqbj-4J-gfAERGDCdOQtVgRhSvIT&index=7&t=0s
</source>
 
 
 
https://www.tutorialesprogramacionya.com/vueya/
 

Revisió de 19:34, 15 març 2024


Vueimagen.png

https://www.youtube.com/watch?v=ub8ZU3JxNsM&list=PL7VXpoQP1k247QUTTxHcYBNyCg1j2ALfD

v-text: para mostrar texto y que no parpadee

v-show: para mostrar u ocultar el elemento en función de su valor. v-show="true" es igual v-show="mensaje"

V-TEXT

<body>
    <div id="el">
            <h1> {{mensaje}}</h1>    <!--podemos ver -->
    </div>
</body>
    
<script src="https://cdn.jsdelivr.net/npm/vue"></script> 
<script>
     var variable = Vue.createApp({
        data: () => ({
            mensaje: "resultado"   //datos, hace referencia dentro de elemento 
        })
    }).mount("#el") //hace referencia al elemento id= el
    
</script>


<body>
    <div id="el">
            <h1>Hola <span v-text="mensaje"> </span></h1>   <!--muestra "Hola" y luego en función del texto del input va rellenando-->
            <input type="text" class="text" v-model="mensaje">
    </div>
</body>
   
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>

    var variable = Vue.createApp({
        data: () => ({
            mensaje: "resultado"
        })
    }).mount('#el');
    
</script>

V-SHOW

v-show: para mostrar u ocultar el elemento en función de su valor. v-show="true" es igual v-show="mensaje"

<body>

    <div id="el">
            <h1 v-show="mensaje.length > 2">Ejemplo <span v-text="mensaje"> {{mensaje}}</span></h1>  <!--al recargar la pagina, se puede ver {{mensaje}} para evitar esto se usa la directiva v-text-->
            <input type="text" class="text" v-model="mensaje">
    </div>
</body>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>

    var variable = Vue.createApp({
        data: () => ({
            mensaje: "resultado"
        })
    }).mount("#el")


</script>


<body>
  <div id="el">
    <h1 v-show="mensaje.length > 2">Hola <span v-text="mensaje"> </span></h1>   <!--si el mensaje es mayor que 2 muestra en caso contrario hace un display:none en css-->
    <input type="text" class="text" v-model="mensaje">
  </div>
</body>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>

  var variable = Vue.createApp({
    data: () => ({
      mensaje: "resultado"
    })
  }).mount("#el")

</script>

V-IF

<body>
  <div id="el">
    <h1 v-if="mensaje.length > 2">Hola <span v-text="mensaje"> </span></h1>    <!--en vez de v-show podemos usar v-if-->
    <h1 v-else>otra</h1>
    <input type="text" class="text" v-model="mensaje">
  </div>
</body>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>

  var variable = Vue.createApp({
    data: () => ({
      mensaje: "resultado"
    })
  }).mount("#el")

</script>

V-FOR

<body>
    <div id="el">
        <ul>
            <!-- <li v-text="profesores[0]"></li> -->
            <li v-for="profesor in profesores" v-text="profesor"></li>
        </ul>
    </div>
</body>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
    var variable = Vue.createApp({
        data: () => ({
            profesores: [      //utilizamos un array con cadenas
                "Julio Noguera",
                "Albert Canela",
                "Alex Salinas"
            ]
        })
    }).mount("#el")
</script>


Recorriendo Objetos

<body>
    <div id="el">
        <ul>
            <!-- <li v-text="profesores[0]"></li> -->
            <li v-for="profesor in profesores" v-text="profesor.nombre"></li>
        </ul>
    </div>
</body>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
    var variable = Vue.createApp({
        data: () => ({    //utilizamos un array con objetos
            profesores: [   
                {nombre:"Julio Noguera"},
                {nombre: "Albert Canela"},
                {nombre: "Alex Salinas"}

            ]
        })
    }).mount("#el")
</script>

Podemos especificar recorrer los objetos y mostrar o acceder a su contenido

<body>
   <div id="el">
        <ul>
            <!-- <li v-text="profesores[0]"></li>-->
            <li v-for="profesor in profesores">
                <span v-text="profesor.nombre"></span>
                <small v-if="profesor.activo">-Activo</small>
                <small v-else>-NO está</small>
               
            </li>
        </ul>
    </div>
</body>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
    var variable = Vue.createApp({
        data: () => ({
            profesores: [{
                    nombre: "Julio Noguera",
                    activo: true
                },
                {
                    nombre: "Albert Canela",
                    activo: true
                },
                {
                    nombre: "Alex Salinas",
                    activo: false
                }

            ]
        })
    }).mount("#el")
</script>

//en Consola del navegador->
// variable.profesores[0].nombre ="Pepe"
// variable.profesores.push({nombre:"Joan Comas",activo:true})

EVENTOS y FUNCIONES

CLICK

Tenemos los datos mensajes y el array de profesores, también el método invertir que se ejecutará cuando se haga click en botón, también es interesante que para acceder a los datos se utiliza this.

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<body>
    <div id="el">
        <input type="text" v-model="mensaje">
        <h1 v-text="mensaje"></h1>
        <!-- <button @click="mensaje=mensaje.split('').reverse('').join('')">BOTON</button> --> 
        <!-- @click es abreviación de v-on:click -->
        <button @click="invertir">INVERTIR</button>
    </div>
</body>

<script>
    var variable = Vue.createApp({
        data: () => ({
            mensaje: "",
        }),
        methods: {
            invertir() {
                this.mensaje = this.mensaje.split('').reverse().join('');
            }
        }
    }).mount("#el");
</script>

Mostrar lista asociando evento click

<style>
.false{background:blue}
.true{background: green}
</style>
<body>
    <div class="container">
        <div id="el">
            <ul>
                <li v-for="profe in profesores">
                    <span v-text="profe.nombre"></span>
                    <span @click="profe.activo=false" v-if="profe.activo" class="false">X</span>
                    <span @click="profe.activo=true" v-else class="true">X</span>

                </li>
            </ul>
            <pre>{{$data}}</pre>
        </div>
    </div>
</body>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
    var variable = Vue.createApp({
        data: () => ({
            profesores: [{
                    nombre: "Julio Noguera",
                    activo: true
                },
                {
                    nombre: "Albert Canela",
                    activo: true
                },
                {
                    nombre: "Alex Salinas",
                    activo: false
                }

            ]

        })
    }).mount("#el");
</script>


BOTÓN- AÑADIR LISTA

KEYUP

Eventos de teclado

<body>
    <div id="el">
        <ul>
            <li v-for="profesor in profesores">
                <span v-text="profesor.nombre"></span>
                <small v-if="profesor.activo">-Activo</small>
                <small v-else>-NO está</small>
            </li>
          <input v-on:keyup.enter="anadir" type="text" v-model="profe" >

            <!-- <input @keyup.enter="anadir" type="text" v-model="profe" > -->
        </ul>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
        var variable = Vue.createApp({
            data:() => ({
              profe: "",
                profesores: [
                  { nombre: "Julio Noguera", activo: true },
                  { nombre: "Albert Canela", activo: true },
                  { nombre: "Alex Salinas", activo: false }
                ]
            }),
            methods: {
                anadir() {
                    this.profesores.push({
                        nombre: this.profe,
                        activo: false
                    });
                    this.profe = ""; // Restableix el valor de profe a una cadena buida després d'afegir-lo
                }
            }
        }).mount("#el");
    </script>
</body>

DIRECTIVA V-BIND

PARA ACTIVAR CLASES

<style>
    .rojo {
        background: red;
    }

    .verde {
        background: green;
    }
    .glyphicon{
        color: white;
    }
</style>
<body>

      <div id="el">
          <ul>
            <!--//en el caso de querer añadir varias clases-->
            <!-- v-bind:class="['glyphicon',tarea.completo ? 'verde': 'rojo']" -->
              <li v-for="tarea in tareas"> 
                  <span v-bind:class="{  
                               'rojo': !tarea.completo,
                               'verde': tarea.completo
                                }" v-text="tarea.nombre" @click="tarea.completo=!tarea.completo" ></span>
                  <input type="checkbox"  v-model="tarea.completo">
              </li>
          </ul>
          <pre>
            {{$data}}
          </pre>
      </div>

</body>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
  var variable = Vue.createApp({
      data: () => ({
          tareas: [
            {
                nombre: "Estudiar",
                completo: true
            },
            {
                nombre: "Repasar",
                completo: true
            },
            {
                nombre: "Examinar",
                completo: false
            }
          ]
      })
  }).mount("#el");
</script>


INCREMENTAR

Como se puede ver, se produce un incremento de voto modificando su atributo directamente.

<body>
    <div class="container">
        <h1>veamos</h1>
        <div>
            <ul>
                <li v-for="storie in stories">
                    <button  @click="storie.votos++">Vote {{storie.politico}}</button>
                    <!-- <button  @click="incrementVote(storie)">Vote {{storie.politico}}</button> -->
                    <pre v-text="storie.votos"></pre>
                </li>
            </ul>
        </div>
        <pre>{{$data}}</pre>
    </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script type="text/javascript">
  const app = Vue.createApp({
    data() {
      return {
        stories: [
          { politico: "julio", votos: 1 },
          { politico: "paco", votos: 2 },
          { politico: "raúl", votos: 3 },
          { politico: "jorge", votos: 4 }
        ]
      };
    },
    methods: {
      incrementVote(storie) {
        storie.votos++;
      }
    }
  }).mount(".container");

</script>

FILTRAR

<div id="aplicacion">
    <input type="range" v-model="minimo" min="0" max="50">  
    <div v-text="minimo"></div>


    <div v-for="dato in filtrar">
      <div v-text="dato.descripcion"></div>
    </div>

    <input type="search" v-model="campo">

    <div v-for="dato in busqueda">
      <div v-text="dato.descripcion"></div>
    </div>

  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script>
    var app = Vue.createApp({
      data:() => ({

        minimo: "5",

        campo: "",

        datos: [{
          codigo: 1,
          descripcion: 'papas',
          precio: 12.52
        }, {
          codigo: 2,
          descripcion: 'naranjas',
          precio: 21
        }, {
          codigo: 3,
          descripcion: 'peras',
          precio: 18.20
        }]
      }),
      computed: {
        filtrar() {
          return this.datos.filter((dato) => dato.precio > this.minimo);
        },
        busqueda() {
          return this.datos.filter((dato) => dato.descripcion.includes(this.campo));
        }

      }
    }).mount("#aplicacion")

  </script>

Componentes

1. Crear una nueva instancia de Vue con Vue.createApp

2. Existen 3 Objetos básicos y fundamentales que estarán en la mayoria de las aplicaciones web: el data y methods.

3. Se debe crear un contenedor con un id igual al del objeto el para establecer el alcance del framework


Crear Nuestro primer Componente Básico

<body>
  <div id="aplicacion">
    <!-- vue está disponible en todo este div-->
    <hola-mundo></hola-mundo>
  </div>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<script>
 

//nueva instacia de Vue : Vue.createApp
  var app= Vue.createApp({
    data:() => ({ //capa de datos

    }),
    methods:
    {

    }
    })
    
    app.component('hola-mundo', {    //debe coincidir con el nombre del componente(etiqueta html)
    template: `<p>
                 Hola mundo
              </p>`
  });
    
    app.mount('#aplicacion')  // el elemento donde se aplicará Vue, en este caso un div con id = main);
</script>



PROPS

Props sirve para interpolar o pasar los valores que hayan dentro del atributo la etiqueta html (inglés, castellano) al objeto component

<body>
  <div id="aplicacion">
    <hola-mundo idioma="ingles"></hola-mundo>
    <hola-mundo idioma="castellano"></hola-mundo>
  </div>
 
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
  
  var app= Vue.createApp({
  })
  
  app.component('hola-mundo', {
    props: ['idioma'],
    template: `<div>
                  <p v-if="idioma=='castellano'">Hola mundo</p>
                  <p v-if="idioma=='ingles'">Hello world</p>
              </div>`
  })
  
  app.mount("#aplicacion")
</script>

</body>

Otro Componente Básico

<body>
 
 <div id="app">
 <ejemplo nombre="Juan" apellido="Perez"></ejemplo> 
 <ejemplo nombre="Alejandra" apellido="Quiroga"></ejemplo> 
</div>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
  
  var app= Vue.createApp({
  })
  
  
  app.component('ejemplo', {
   props: ['nombre', 'apellido'],
   template: '<p> Hola {{nombre}} {{apellido}} </p>' 
  });

  app.mount("#app")
</script>

</body>

Ejemplo de Componente, podemos ver que pasamos una peliculas "peliculon 1917" y una imagen en la etiqueta peliculas, que serán los valores que recibirá el componente para luego incluirlo en la plantilla.

<body>
  <div class="container">
    <peliculas titulo="peliculon 1917"
      imagen="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcSexz8IyOhoxR2ibVc78RHzpBCsvhDt3fx0wl99Qcxacht4gk9z"></peliculas>
  </div>


<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script type="text/javascript">
  

  var app = Vue.createApp({
  
  })
  
  app.component('peliculas', {

    props: ['imagen', 'titulo'],  //los props reciben los datos externos del html en este caso será "peliculon 1917" y la ruta de la imagen
    template: 
      `<div>
      <img width="100px" v-bind:src="imagen" :alt="titulo"/>  <!-- v-bind:alt se reduce en :alt , al ser un atributo no se puede usar {{}} sino v-bind-->
      <h2> {{titulo}} </h2>
      </div>`
  });
  
  app.mount(".container")

</script>
</body>


Este ejemplo, viene a basarse en el ejemplo anterior pero además coje datos del JSON data y los va mostrando

<body>
  <div class="container">
    <div v-for="(dato, index) in datos">   <!-- Corregido -->
      <peliculas :key="index" :titulo="dato.titulo" :imagen="dato.imagen">
      </peliculas>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue"></script>

  <script type="text/javascript">
		var app = Vue.createApp({
      data: () => ({
          datos: [{
              titulo: "star wars",
              imagen: "https://vignette.wikia.nocookie.net/cine/images/8/88/Sw1.jpg/revision/latest?cb=20120930202439 "
            },
            {
              titulo: "Sonic",
              imagen: "https://www.smashbros.com/wiiu-3ds/images/character/sonic/main.png"
            },
            {
              titulo: "Mario bros",
              imagen: "https://imagenesparapeques.com/wp-content/uploads/2021/05/Mario-Bros-png-transparente.png"
            }
          ]

        })
    })

    app.component('peliculas', {
     props: ['titulo', 'imagen'],
      template: `<div>
        <img width="100px" :src="imagen" :alt="titulo"/>
        <h2>{{ titulo }}</h2>
      </div>`
    });
    
		app.mount(".container")

  </script>
</body>


Componentes: definición de métodos y modelo de datos


<body>
  <div id="el" class="container">
    <h1> Helados </h1>
    <h2> Lista </h2>
    <ul>
      <li v-for="item in helados" :key="item.sabor">
        <component-helado v-bind:helado="item"></component-helado>
      </li>
    </ul>
    <h2> Seleccionados </h2>
    <ul>
      <li v-for="item in heladosSeleccionados" :key="item.sabor"> {{ item.sabor }} </li>
    </ul>
  </div>
</body>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script type="text/javascript">
    var app = Vue.createApp({
      data: () => ({
        helados: [{
            sabor: 'Chocolate',
            seleccionado: false
          },
          {
            sabor: 'Dulce de leche',
            seleccionado: false
          },
          {
            sabor: 'Frutilla',
            seleccionado: false
          },
          {
            sabor: 'Limón',
            seleccionado: false
          },
          {
            sabor: 'Vainilla',
            seleccionado: false
          }
        ]
      }),
      computed: {
        heladosSeleccionados() {
          return this.helados.filter(helado => helado.seleccionado);
        }
      }
    });

    app.component('component-helado', {
      props: ['helado'],
      template: `
        <div> 
          <button class="btn btn-success" v-on:click="agregar(helado)" v-if="!helado.seleccionado"> + </button> 
          <button class="btn btn-danger" v-on:click="eliminar(helado)" v-if="helado.seleccionado"> - </button> 
          <span> {{ helado.sabor }} </span> 
          <hr/>  
        </div>  `,
      methods: {
        agregar(helado) {
          helado.seleccionado = true;
        },
        eliminar(helado) {
          helado.seleccionado = false;
        }
      }
    });

    app.mount('#el');
</script>

Ejercicios

v-if, v-else, v-else-if, v-show

Crear dos inputs de tipo password y mostrar un mensaje en caso de que sean iguales

solución:

<body>
  <div id="aplicacion">
    <p>Ingrese la clave:
      <input type="password" v-model="clave1">
    </p>
    <p>Repita la clave:
      <input type="password" v-model="clave2">
    </p>  
    <p v-if="clave1===clave2">Las claves son iguales.</p>
    <p v-else>Las claves son distintas.</p>
  </div>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script>
    var app = Vue.createApp({
      data:() => ({ 
        clave1 : '',
        clave2 : ''
      })
    }).mount("#aplicacion")
  </script>
</body>


v-for

Crear un array en data con los días de la semana y generar una tabla de 1 columna y 7 filas en HTML

solución:

<body>
  <div id="aplicacion">
    <table border="1">
      <template v-for="dia in dias">
        <tr><td>{{dia}}</td></tr>
      </template>
    </table>
  </div>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script>
    var app= Vue.createApp({
      data:() => ({ 
        dias: ['lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado', 'domingo']
      })
    }).mount("#aplicacion")
  </script>
</body>


v-for con array de objetos literales

Definir un array con objetos que almacenan los nombres y edades de 6 personas. Mostrar en una lista ordenada el nombre de cada persona y entre paréntesis si es mayor o no de edad.

personas: [{
                    nombre: 'Julio', 
                    edad: 32
                   },{
                    nombre: 'Albert', 
                    edad: 50
                   },{
                    nombre: 'Alex', 
                    edad: 35
                   },{
                    nombre: 'Ramón', 
                    edad: 50
                   }]

solución:

<body>
  <div id="aplicacion">
    <ul>
      <template v-for="persona in personas">
        <li>
          {{persona.nombre}}
          <span v-if="persona.edad>=18">(Mayor)</span>
          <span v-else>(Menor)</span>
        </li>
      </template>
    </ul>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue"></script>   
  <script>
    var app= Vue.createApp({
      data:() => ({ 
        personas: [{
                    nombre: 'Jose', 
                    edad: 12
                   },{
                    nombre: 'Ana', 
                    edad: 43
                   },{
                    nombre: 'Pedro', 
                    edad: 4
                   },{
                    nombre: 'María', 
                    edad: 12
                   }]

      })
    }).mount("#aplicacion")
  </script>
</body>


methods

Se desea mostrar una lista de tareas, se pide que se pueda eliminar el item seleccionado.

Solución:

<body>
    <div id="el"> 
        <div v-for="tarea in tareas" >    <div v-for="(item, index) in tareas" > 
            <div v-text="tarea" ></div> <span @click="eliminar(tarea)">X</span>
         </div>
        <input type="text" v-model="tarea">
        <button @click="anadir">+</button>
        
        <br>
        {{$data}}

    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
        var variable = Vue.createApp({
            data() {
                return {
                    tarea: "",
                    tareas: []
                }
            },
            methods: {
                anadir() {
                    this.tareas.push(this.tarea);
                    console.log(this.tareas);
                },
                eliminar(tarea) {
                    let index = this.tareas.indexOf(tarea);
                    if (index !== -1) {
                        this.tareas.splice(index, 1);
                    }
                }
            }
        }).mount('#el');
    </script>
</body>

</html>


Eventos: v-on:keypress, v-on:keyup

Tenemos un input de tipo text que introducimos un texto, a medida que vayamos escribiendo texto deberá ir mostrando la cantidad de 'a' y 'A' que hay


Componentes en Vue

Crear una componente llamada 'acerca-de' que muestre el nombre del programa y la versión del mismo.


https://www.tutorialesprogramacionya.com/vueya/

https://www.youtube.com/watch?v=jfEEQVdbl54&list=PLPl81lqbj-4J-gfAERGDCdOQtVgRhSvIT&index=7&t=0s