Ejercicios de práctica

14/38

Lectura

Práctica Módulo 2

Armar un simple “tracker” de cursos, que permita calcular y registrar la cantidad cursos de Platzi tomados y obtener la suma de las horas invertidas en tu educacion.

Haz fork de este CodePen para obtener la estructura basica del proyecto:

Consideraciones:

  • La aplicación debe cumplir los siguientes lineamientos:
    • Un propiedad courses que sea un array y permita almacenar la lista de cursos.
    • Tener una propiedad title y otra time que se usean para agregar un nuevo curso a la lista, estas propiedades deben estar enlazados a los inputs usando v-model.
    • Un boton con un metodo addCourse (enlazado con v-on) que permita agregar un nuevo courso usando los valores de title y time.
    • Una propiedad computada totalTime que recorra toda la lista de cursos y retorne la suma del tiempo invertido en educacion.
    • Mostrar la lista de cursos tomados, con el titulo de los mismos y las horas de cada uno usando v-for.
    • Mostrar el total de horas con totalTime, en caso que no existan cursos se debe mostrar un mensaje indicandolo.

Solución

Aportes 334

Preguntas 0

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Hola Devs:
-Les traigo algo maravilloso, pueden checar el proyecto que he realizado y colaborar en cualquier cosa que deseen mejorar.
-Tambien les invito a participar de la dinamica, y es que vayan al repositorio, coloquen su nombre en el array de students en el archivo JS y haganme un Pull Request, asi estaran dentro de la lista de estudiantes que forman parte de la comunidad, aceptare todos los pull request, te espero. [Puedes acceder desde tu dispositivo movil, es responsive]
Link del repositorio: Click Aqui
Link del proyecto en produccion: Click Aqui

Recuerda, #NuncaParesDeAprender 💚

Adapte un poco mucho la idea de la lista e hice un ayudante para listas de mercado.

https://londrack.github.io/Alikar-market-list/
https://github.com/Londrack/Alikar-market-list

Me costo 😅… pero lo conseguí 😁

Listo! tuve cierta dificultad con la parte de totalTime pero este es el resultado:

Repositorio: https://github.com/JuanesGalvis/FirstPage_VueJS

Les comparto como lo resolvi yo! https://codepen.io/federicowalovnik/pen/rNWOMgO

Les dejo el enlace a mi solución.

https://codepen.io/pepeloperweb/pen/MWjymPq

Reto cumplido!!

Hola, les comparto mi solución… cambie algo en los estilos. Les agradezco cualquier comentario. Gracias!

https://codepen.io/kevcb1988/pen/povdZPd

Hola, Reto cumplido. Los estilos de botones e inputs use Boostrap. Link

Chicos qué tal!, este es mi intento del reto, espero que les guste 😄
Repositorio: Link
Link del proyecto: Link

Mi solución

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Reto 1</title>
    <link rel="stylesheet" href="/styles.css">
</head>
<body>
    <div id="app">
        <h1>
          Mis Cursos de Platzi💚
        </h1>
          <p>
            <input type="text" v-model="title" placeholder="Titulo del curso"/>
          </p>
          <p>
            <input type="number" v-model.number="time" placeholder="Horas"/>
          </p>
          <p>
            <button v-on:click="addCourse">Guardar Curso</button>
          </p>
        </fieldset>
        <div>
          <h3>Lista de Cursos</h3>
          <p class="red" v-if="courses.length<1">Aun no has realizado cursos</p>
          <div v-if="courses.length>=1">
            <ol>
              <!-- Lista de cursos -->
              <li v-for="course in courses">
                  {{course.title}} : {{course.time}} {{course.time>1? 'horas':'hora'}}
              </li>
            </ol>
            <hr/>
            <p>
              Llevo <strong>{{ totalTime }}</strong> horas aprendiendo en Platzi.
              <b>#NuncaParesDeAprender 💚</b>
            </p>
          </div>
        </div>
      </div>
      <!--Librería VUE.JS-->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
  <script src="app.js"></script>
</body>
</html>

app.js

new Vue({
    el: '#app',
    
    data () {
      return {
        courses :[],
        title :"",
        time:0
      }
    },
    
    computed: {
        totalTime(){
            var suma = 0;
            var listCurses = this.courses
            for(var i = 0; i < listCurses.length; i++){
                var time = listCurses[i].time;
                suma += time;
            }
            return suma;
        }
    },
    
    methods: {
        addCourse(){
            if((this.time != "" &&this.time!= null)||this.time ===0){
                this.courses.push({title:this.title,time:this.time});
                this.title = "";
                this.time = 0;
            }else {
                swal({
                    text: "Dato invalido",
                    icon: "error",
                  });
            }
            
        }
    }
  })```



¡Ejercicio Resuelto!
Codepen
Imagen Previa:

Hola, Aquí les dejo mi solución y le agregué un poquito de CSS porque ¿Por qué no? #frontendlifestyle 🔥

Mi solucion al modulo: Aqui

Solución Modulo 1: Este enlace…

script

new Vue({
  el: '#app',
  
  data () {
    return {
      title:"",
      courses:[],
      time:0
    }
  },
  
  computed: {
        totaltime(){
   let suma = 0
  this.courses.forEach(course => {suma += parseInt(course.time)});
  return`${suma}`
}
        }, 
    methods: {
    addcourse(){
      title=this.title,
        time=this.time
      this.courses.push({
        title, time
      })
    }
  }
})```


html


<div id=“app”>
<h1>
Mis Cursos de Platzi💚
</h1>
<p>
<input type=“text” placeholder=“Titulo del curso” v-model=“title”/>
</p>
<p>
<input type=“number” placeholder=“Horas” v-model=“time” />
</p>
<p>
<button v-on:click=“addcourse”>Guardar Curso</button>
</p>
</fieldset>
<div>
<h3>Lista de Cursos</h3>
<p class=“red” v-if=“courses == false” >Aun no has realizado cursos</p>
<div>
<ol>
<!-- Lista de cursos -->
<li v-for="(curso,i) in courses">{{curso.title}} - {{curso.time}}</li>
</ol>
<hr/>
<p>
Llevo <strong>{{ totaltime }}</strong> horas aprendiendo en Platzi.
<b>#NuncaParesDeAprender 💚</b>
</p>
</div>
</div>
</div>

Me tomo algo de tiempo, pero al fin lo complete 😛

<div id="app">
    <h1>
      Mis Cursos de Platzi💚
    </h1>
      <p>
        <input v-model="title" type="text" placeholder="Titulo del curso"/>
      </p>
      <p>
        <input v-model="time" type="number" placeholder="Horas"/>
      </p>
      <p>
        <button v-on:click="addCourse">Guardar Curso</button>
      </p>
    </fieldset>
    <div>
      <h3>Lista de Cursos</h3>
      <p class="red" v-if="courses.length === 0">Aun no has realizado cursos</p>
      <div>
        <ol>
          <!-- Lista de cursos -->
          <li 
            v-if="course"
            v-for="course in courses"
          >
          <strong>Titulo:</strong> {{course[0]}} <strong>Tiempo:</strong> {{course[1]}}
        </li>
        </ol>
        <hr/>
        <p>
          Llevo <strong v-if="totalTime > 0">{{ totalTime }}</strong> <strong v-else>0</strong> horas aprendiendo en Platzi.
          <b>#NuncaParesDeAprender 💚</b>
        </p>
      </div>
    </div>
  </div>

Y aqui el JS:

new Vue({
  el: '#app',
  
  data () {
    return {
      courses: [],
      title: '',
      time: '',
      course: '',
    }
  },
  
  computed: {
    totalTime() {
      let total = 0
      this.courses.forEach(course => {
        total = parseInt(total += parseInt(course[1]));
      });
      return total 
    }
  },
  
  methods: {
    addCourse() {
      this.course = [this.title, this.time];
      this.courses.push(this.course);
    }
  }
})

Listo, dejo enlace del ejercicio

JavaScript

HTML

Instancia de vue.

new Vue({
  el: '#app',  
  data () {
    return {
      courses: [],
      course: {},
    }
  },  
  computed: {
    totalTime(){
      let total = 0;
      this.courses.forEach( course => { total = total + parseInt(course.time); });
      return total;
    }
  },  
  created(){
    this.initCourse();
  },  
  methods: {
    initCourse(){
      this.course = { title: "", time: 0 };
    },
    addCourse(){
      this.courses.push(this.course);
      this.initCourse();
    }
  }
})

Template

<div id="app">
  <h1>
    Mis Cursos de Platzi💚
  </h1>
    <p>
      <input v-model="course.title" type="text" placeholder="Titulo del curso"/>
    </p>
    <p>
      <input v-model="course.time" type="number" placeholder="Horas"/>
    </p>
    <p>
      <button v-on:click="addCourse">Guardar Curso</button>
    </p>
  </fieldset>
  <div>
    <h3>Lista de Cursos</h3>
    <p class="red">Aun no has realizado cursos</p>
    <div>
      <ol>
        <!-- Lista de cursos -->
        <li v-for="(course, index) in courses">
          Curso: {{course.title}} / Horas: {{course.time}}
         </li>
      </ol>
      <hr/>
      <p>
        Llevo <strong>{{ totalTime }}</strong> horas aprendiendo en Platzi.
        <b>#NuncaParesDeAprender 💚</b>
      </p>
    </div>
  </div>
</div>

Hay algunos errores Team Platzi, “Usean”, “courso”…

Termine la leccion!
http://simple-police.surge.sh/

listo!

Ya terminé mi proyecto!
Link a mi github: https://github.com/zerofelx/Curso-Vuejs/tree/master/Ejercicio
Link para verlo directamente: https://zerofelx.github.io/Curso-Vuejs/Ejercicio/index.html

Fue muy divertido! 😄

Agregé un boton para eliminar el último registro
https://codepen.io/jorgiearango/pen/NWPvMYQ

El código se encuentra aquí
y así se visualiza y ejecuta en github-pages

index.pug

<!DOCTYPE html>
html(lang="en")
  head
    meta(charset="UTF-8")
    meta(name="viewport", content="width=device-width, initial-scale=1.0")
    link(rel="stylesheet", href="../css/style.css")
    title Cursos Platzi
  body
    #app 
      .content
        .leftContent
          h1 Mi Cursos de Platzi 💚 
          input(v-model="title" type="text" placeholder= "Titulo del curso")
          input(v-model="time" type="number" placeholder= "Número de horas")
          button(@click="addCourse" type='submit') Guardar Curso
        .rightContent
          h3 Lista de Cursos
          p(v-show='courses.length <= 0 ? true:false' class = "red") Aun no has tomado cursos
          ol
            li(v-for='c in courses' :key='c.title') {{ c.title }}
          p Llevo
            strong {{ totalTime }}
            horas aprendiendo en Platzi. 
            b #NuncaParesDeAprender 💚 

  script(src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js")
  script(src="../js/script.js")

style.scss

*{
  font-family: Arial, Helvetica, sans-serif;
}
html {
  padding: 20px;
  color: #3d3d3d;
}

.content{
  width: 70%;
  display: flex;
  border: 1px solid rgba($color: gray, $alpha: .6);
  background-color: #f1f3f4;
  box-shadow: 0px 20px 33px 0px rgba($color: #000000, $alpha: 0.50);
  padding: 35px;
  border-radius: 25px;
}
.leftContent{
  display: flex;
  flex-direction: column;
  width: 50%;
  input{
    max-width: 250px;
    height: 40px;
    margin-top: 20px;
    padding: 0 10px;
    font-size: 16px;
    border-radius: 5px;
  }
  button{
    max-width: 180px;
    height: 40px;
    margin-top: 20px;
    font-size: 16px;
    border-radius: 10px;
  }
}
.rightContent{
  padding: 40px;
  width: 40%;
  width: 50%;
}
.red {
  color: tomato;
}

script.js

var app = new Vue({
  el : "#app",
  data(){
    return {
      courses :[],
      title: '',
      time: '',
    }
  },
  computed:{
    totalTime(){
      const toNumber = this.courses.map(c => parseInt(c.time))
      const suma = toNumber.reduce((a,b) => a+b, 0);
      return suma;
    }
  },
  methods:{
    addCourse() {
      var newCourse = this.courses.push({
        title: this.title,
        time: this.time,
      });
      return this.courses;
    }
  }
})

Aquií esta mi solución:
https://codepen.io/ftalero/pen/qBOoggE

Aquí dejo mi solución al ejercicio:
https://codepen.io/fernandrewm/pen/NWGarOj

Hola Profe Nacho y a todos ! Dejo mi solución. Muchas gracias.
https://codepen.io/abreguabel/pen/jObapgm

Eh aquí forma de resolverlo:
HTML

<div id="app">
  <h1>
    Mis Cursos de Platzi💚
  </h1>
    <p>
      <input type="text" placeholder="Titulo del curso" v-model="title" />
    </p>
    <p>
      <input type="number" placeholder="Horas" v-model="time" />
    </p>
    <p>
      <button v-on:click="addCourse">Guardar Curso</button>
    </p>
  </fieldset>
  <div>
    <h3>Lista de Cursos</h3>
    <p v-if="courses == 0" class="red">Aun no has realizado cursos</p>
    <div v-else>
      <ol v-for="p in courses"
          v-bind:key="p.title">
        <!-- Lista de cursos -->
        <li>{{ p.title }}, con {{ p.time }} horas</li>
      </ol>
      <hr/>
      <p>
        Llevo <strong>{{ totalTime }}</strong> horas aprendiendo en Platzi.
        <b>#NuncaParesDeAprender 💚</b>
      </p>
    </div>
  </div>
</div>

JS

new Vue({
  el: '#app',
  
  data () {
    return {
      courses: [],
      title: '',
      time: null,
    }
  },
  
  computed: {
    totalTime(){
      let temp = 0
      this.courses.forEach(p => {
        temp += parseInt(p.time)
      })
      return temp
    }
  },
  
  methods: {
    addCourse(){
      let newCourse = { title: this.title, time: this.time }
      this.courses.push(newCourse)
      this.title = ''
      this.time = null
    }
  }
})

Hola!

Les comparto mi proyecto, pueden ver el código en CodePen: CodePen

Ejercicio cumplido.

Dejo Aqui mi proyecto. Aparte de lo requerido, le agregue:

  • La opción de poder eliminar un curso que ya estuviera en la lista.

  • La opción de poder cambiar el modo del tema (Modo oscuro / Modo claro)


Reto cumplido.

HTML

<div id="app">
  <h1>
    Mis Cursos de Platzi💚
  </h1>
    <p>
      <input type="text" v-model="title" placeholder="Titulo del curso"/>
    </p>
    <p>
      <input type="number"  v-model="time" placeholder="Horas"/>
    </p>
    <p>
      <button v-on:click="addCourse">Guardar Curso</button>
    </p>
  </fieldset>
  <div>
    <h3>Lista de Cursos</h3>
    <p class="red" v-if="totalTime==0">Aun no has realizado cursos</p>
    <div>
      <ol>
        <!-- Lista de cursos -->
        <li v-for="course in courses">{{course.title}} - {{course.time}}</li>
      </ol>
      <hr/>
      <p>
        Llevo <strong>{{ totalTime }}</strong> horas aprendiendo en Platzi.
        <b>#NuncaParesDeAprender 💚</b>
      </p>
    </div>
  </div>
</div>

JS

new Vue({
  el: '#app',
  
  data () {
    return {
      courses:[],  
      title:'',
      time:0,
    }
  },
  
  computed: {
    totalTime(){
      return this.courses.reduce((sum,s) => sum + parseInt(s.time),0)
    },
  },
  
  methods: {
    addCourse(){
      this.courses.push({title:this.title,time:this.time});
      this.title="";
      this.time=0
    }
  }
})

JS

new Vue({
  el: "#app",

  data() {
    return {
      title_v: "",
      time_v: "",
      courses: [],
    };
  },

  computed: {
    totalTime() {
      if (!this.courses.length) {
        return 0;
      }

      return this.courses.reduce((a, b) => a + parseInt(b.time), 0);
    },
  },

  methods: {
    saveCourses() {
      console.log("Guardó");
      this.courses.push({
        title: this.title_v,
        time: this.time_v + " hrs",
      });
      this.title_v = "";
      this.time_v = "";
    },
  },
});

HTML

  <div id="app" class="app">
    <h1>
      Mis Cursos de Platzi💚
    </h1>
      <p>
        <input v-model="title_v" type="text" placeholder="Titulo del curso"/>
      </p>
      <p>
        <input v-model="time_v" type="number" placeholder="Horas"/>
      </p>
      <p>
        <button v-on:click="saveCourses">Guardar Curso</button>
      </p>
    </fieldset>
    <div>
      <h3>Lista de Cursos</h3>
      <p v-if="courses == 0" class="red">Aun no has realizado cursos</p>
      <p v-else="courses > 0" class="red">Aun no has realizado cursos</p>
      <div>
        <ol>
            <li
            class="uppercase"
            v-for="(p) in courses"
            v-bind:key="p.title">
              {{p.title}} - {{p.time}}
            </li>
        </ol>
        <hr/>
        <p>
          <strong v-if="courses == 0">Aun no llevo cursos en Platzi 💔</strong>
          <strong v-else="courses > 0">Llevo {{ totalTime }} horas aprendiendo en Platzi.</strong>
          <b>#NuncaParesDeAprender 💚</b>
        </p>
      </div>
    </div>
  </div>

JS

Este es la resolución del reto, es grandioso todo lo que he aprendido!!!

app.js

new Vue({
    el: '#app',
    
    data () {
      return {
        state:false,
        title:'',
        time:0,
        courses:[],
      }
    },
    methods:{
      addCourse(){
          if(this.title==='' && parseInt(this.time)===0){
           
          }else{
            this.state=true
          this.courses=[...this.courses,{title:this.title,time:this.time}]
          this.title=''
          this.time=0

          }    
        console.log(this.courses); 
      }
    },
    computed:{
      totalTime(){
        let totalT=0;
        this.courses.map(curso=>
          {
          totalT=totalT+parseInt(curso.time )
        })
        return totalT
      }
    }

    
    
    
  })

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <title>Cursos platzi</title>
</head>
<body>
    <div id="app">
        <h1>
          Mis Cursos de Platzi 💚
        </h1>
          <p>
            <input type="text" class="title-input form-control" v-model="title" placeholder="Titulo del curso"/>
          </p>
          <p>
            <input type="number" class="time-input form-control" v-model="time" placeholder="Horas"/>
          </p>
          <p>
            <button type="button"  v-on:click="addCourse" class="btn btn-dark">Guardar Curso</button>
          </p>
        </fieldset>
        <div>
          <h3>Lista de Cursos</h3>
          
          <p class="red" v-show="!state">Aun no has realizado cursos</p>
          <div>
            <ul v-show="state" >
              <li v-for="(course, index) in courses" :key="index" class="py-2">
                {{course.title}} con {{course.time}} horas 
            </li>
            </ul>
            <hr/>
            <p>
              Llevo <strong>{{ totalTime }}</strong> horas aprendiendo en Platzi.
              <b>#NuncaParesDeAprender 💚</b>
            </p>
          </div>
        </div>
      </div>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="index.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>   
   
</body>
</html>

Mi solución:

new Vue({
    el: '#app',
    
    data () {
      return {
        title: '',
        time:0,
        courses: [],
      }
    },
    
    computed: {
        totalTime(){
            let time = 0
            for (const c of this.courses) {
                time += c.time
            }

            return time
        }
    },
    
    methods: {

        addCourse(){
            this.courses.push({title:this.title,time:parseInt(this.time)})   
        }
        
    }
})

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <title>Cursos platzi</title>
</head>
<body>
    <div id="app">
        <h1>
          Mis Cursos de Platzi 💚
        </h1>
          <p>
            <input type="text" class="title-input form-control" v-model="newTitle" placeholder="Titulo del curso"/>
          </p>
          <p>
            <input type="number" class="time-input form-control" v-model.number="newTime" placeholder="Horas"/>
          </p>
          <p>
            <button type="button"  @click="addCourse" class="btn btn-dark">Guardar Curso</button>
          </p>
        </fieldset>
        <div>
          <h3>Lista de Cursos</h3>
          
          <p class="red" v-show="!state">Aun no has realizado cursos</p>
          <div>
            <ul v-show="state" >
              <li v-for="(curso,index) in courses" class="py-2" :key="index">
                <input v-show="stateButton" class="editarElemento" v-model="curso.title" type="text">
                <input v-show="stateButton" class="editarElemento" v-model.number="curso.hour"  type="number">
                {{curso.title}}  con {{curso.hour}} Horas  
              <button @click="editarElement" class="editar bg-warning">editar</button>
              <button @click="guardarElement" class="editar bg-primary">guardar</button>
            </li>
            </ul>
            <hr/>
            <p>
              Llevo <strong>{{ totalTime }}</strong> horas aprendiendo en Platzi.
              <b>#NuncaParesDeAprender 💚</b>
            </p>
          </div>
        </div>
      </div>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="app.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>   
</body>
</html>

JS

new Vue({
    el: '#app',
    
    data () {
      return {
        newTitle:'',
        newTime:'',
        state:false,
        stateButton:false,
        
        courses:[
          {title:"", hour:0}
        ],

      }
    },

    
    computed: {
      totalTime(){
        let count=0;
        this.courses.map((element)=>{
          count=count+element.hour
        })
        console.log(count);
        return count;
        }
     


    },
    
    methods: {
      addCourse(){
        if(this.courses.hour!==0){
          this.courses.push({
            title:this.newTitle,
            hour:this.newTime
          })
          console.log("ingreso aqui");
        } 
        this.newTime="",
        this.newTitle="",
        this.state=true 
      },
      editarElement(){
      this.stateButton=true
          
      },
      guardarElement(){
        this.stateButton=false
      }

    }
  })

Acá les traigo la solución implemente Swal para que me diera una alerta llevo tiempo con vue y se me hizo super sencillo.

https://codepen.io/ethanjesuan/pen/qBpjvQv

Espero les guste mi implementación, me gustaría algo similar en la sección Mi Ruta 😉


video

Aquí les dejo mi solución al desafío.
Dejé bien comentado el código.
https://github.com/EricConchaParra/courseTracker

Hola dejo el ejercicio resuelto:
https://codepen.io/fedeesti/pen/vYWbzxx

Asi va:



A decir verdad me tomó bastante tiempo, pero se logró al final.
La parte de CSS en sí fue mas Bootstrap para facilitar las cosas.
Link repositorio GitHub
Quizás mas adelante le haga mejoras o lo ponga mas presentable. Aun falta mucho por aprender.

Esta es mi solución:

Le añadí también un botón para eliminar el último curso agregado a la lista, me gustó muchísimo y aclara mucho los conceptos!!

Repositorio:
https://github.com/esvelpe/CursoBasicoVue2

Dejo mi ejercicio por aquí:
https://codepen.io/gadeveloper/full/abVwLWe

Repositorio público: https://github.com/willywaooo182/vue-track.git

Recursos Webs: Bootstrap 5, [email protected], Html 5, Java Script, Imagenes de Vue

El Código esta comentado para mejor uso y son libres de usarlo…

Logrado, aun falta un montón en diseño!

Yo lo hice asi en codepen directamente:

HTML:

<div id="app">
  <h1>
    Mis Cursos de Platzi💚
  </h1>
    <p>
      <input v-model="title" type="text" placeholder="Titulo del curso"/>
    </p>
    <p>
      <input v-model="time" type="number" placeholder="Horas"/>
    </p>
    <p>
      <button @click="addCourse">Guardar Curso</button>
    </p>
  </fieldset>
  <div>
    <h3>Lista de Cursos</h3>
    <p v-show="courses.length === 0" class="red">Aun no has realizado cursos</p>
    <div>
      <ol v-for="course in courses" v-bind:key="course.courseName">
        <!-- Lista de cursos -->
        <li>
            {{ course.courseName }} - {{ course.hours + " horas"}}
        </li>
        
      </ol>
      <hr/>
      <p>
        Llevo <strong>{{ totalTime }}</strong> horas aprendiendo en Platzi.
        <b>#NuncaParesDeAprender 💚</b>
      </p>
    </div>
  </div>
</div>

JS:

new Vue({
  el: '#app',
  
  data () {
    return {
      courses: [],
      title: '',
      time: 0
    }
  },
  
  computed: {
    totalTime(){
      let totalHours = 0;
      
      for (let item of this.courses) {
        totalHours = totalHours + item.hours;
      }
      
      return totalHours;
    }
  },
  
  methods: {
    addCourse(){
      let course = {
        courseName: this.title,
        hours: parseInt(this.time)
      }
      
      this.courses.push(course);
    }
    
  }
})



Les comparto mi código en CodePen

Me dio dificultad pero lo logre

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="app">
        <h1>
          Mis Cursos de Platzi <span class="verde">💚</span>
        </h1>
        <p v-show="error">{{ error ?'debe llenar ambos campos':'pk'}}</p>
          <p>
            <input type="text" v-model="title" placeholder="Titulo del curso"/>
          </p>
          <p>
            <input type="number" v-model="time" placeholder="Horas"/>
          </p>
          <p>
            <button @click="addCourse">Guardar Curso</button>
          </p>
        </fieldset>
        <div>
          <h3>Lista de Cursos</h3>
          <p class="red">Aun no has realizado cursos</p>
          <div>
            <ol>
              <!-- Lista d e cursos -->
              <li v-for="{ title,time} = curso  in course">
                  {{ title }} - {{ time }}
              </li>
            </ol>
            <hr/>
            <pre>{{ $data }}</pre>
            <p>
              Llevo <strong>{{ totalTime }}</strong> horas aprendiendo en Platzi.
              <b>#NuncaParesDeAprender 💚</b>
            </p>
          </div>
        </div>
      </div>
      
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    <script src="./app.js"></script>
</body>
</html>
const app = new Vue({
    el: '#app',
    
    data () {
      return {
          error:false,
          course:[],
          title:'',
          time: '',
      }
    },
    
    methods: {
        addCourse (){
            if (this.title.length > 0 && this.time.length > 0) {
                this.course.push(
                    {
                    title: this.title,
                    time:  this.time,
                    })
                
            }else{
                this.error = true

                if (this.error === true) {
                    setTimeout(() => {
                        this.error = false
                    }, 3000);
                }
             }
            this.title = ''
            this.time = ''

            console.log(this.course)
            

        }
    },
    computed: {
        totalTime() {
           let time = 0
           this.course.map((el) => {
            time += parseInt(el.time)
           })

           return time
            
        }
    },
    
  })

Listo! Comparto el enlace al fork de Codepen y una captura de pantalla

https://codepen.io/terracing/pen/bGoEwKz

https://codepen.io/pachecosc/pen/WNEVvmq

he visto que la mayoria tiene problemas al momento de hacer validaciones. aqui dejo mi aporte.
ademas agregue una lista de cursos pre establecidos estos solo aparecen al dar click y solo se agregan cuando la lista esta vacia… cuando ya se agregaron una vez ya no lo dejan agregar, lo mismo con la validacion de no ingresar cursos con nombre vacio o tiempo igual a cero

Así quedo el mio

¡Completado!

Listo! Sin diseño pero almenos funciona jaja

Un saludo
Pues no es bonito como la mayoria de los proyectos, pero es funcional.
Espero criticas para mejorar.
Muchas gracias.

git: https://github.com/lhosorioq/plazi-cursos-vue

imagen:

Definitivamente el CSS no es mi mejor aliado. XD

  • Repo ver rama develop

  • Novedades:

    • Si se agregan horas menores o iguales a cero no se registra el curso
    • Si se agrega un curso ya eblistado, las horas agregadas se suman (no se agrega uno nuevo)
  • Caso 1 (Cursos sin registrar)

  • Caso 2 (Cursos registrados)

Agregué la opcion de remover los cursos de la lista con la ❌, tambien se actualizan las horas aprendidas cuando se quitan cursos.

Reto realizado 😃

Link github pages

hecho

Listo reto cumplido, me tomo más hacer la lógica que el diseño jejje, pero me gusto el reto me ayudo a tener más clara la bases.
Aqui el Codepen: https://codepen.io/admiralpxl/pen/GRmVNbV?editors=1101

Comparto mi respuesta. No he trabajado el diseño, porque no es lo que más me interesa por el momento.

https://codepen.io/ianaya89/pen/rNNZYLY

Comparto solucion

Aqui les comparto mi codigo

<div id="app">
  <h1>
    Mis Cursos de Platzi💚
  </h1>
    <p>
      <input type="text" placeholder="Titulo del curso" v-model="title"/>
    </p>
    <p>
      <input type="number" placeholder="Horas" v-model="time"/>
    </p>
    <p>
      <button @click="addCourse">Guardar Curso</button>
    </p>
  </fieldset>
  <div>
    <h3>Lista de Cursos</h3>
    <p class="red" v-if="courses.length === 0">Aun no has realizado cursos</p>
    <div>
      <ol>
        <!-- Lista de cursos -->
        <li v-for="c in courses"><strong>Titulo: {{c.title}} </strong> - Horas: {{c.time}}</li>
      </ol>
      <hr/>
      <p>
        Llevo <strong>{{ totalTime }}</strong> horas aprendiendo en Platzi.
        <b>#NuncaParesDeAprender 💚</b>
      </p>
    </div>
  </div>
</div>

new Vue({
  el: '#app',
  
  data () {
    return {
      courses: []
    }
  },
  
  computed: {
    totalTime(){
      let timeCourses = 0;
      for (var item of this.courses){
        timeCourses = timeCourses + Number(item.time);
      }
      return timeCourses;
    }
  },
  
  methods: {
    addCourse() {
      let course = {
        title: this.title,
        time: this.time
      }
      this.courses.push(course);
    }
  }
})

Buenas devs, les comparto mi código del reto https://codepen.io/alver23-the-reactor/pen/abWNeWx

![](
![](

app.js

new Vue({
  el: '#app',
  data(){
    return{
      courses:[], //lista de cursos
      title: null, 
      time: 0
    }
  },
  methods:{
    addCourses(){
      if(!this.title || !this.time){
        alert('No dejes campos vacios');
        return
      }else{
        this.courses.push({title:this.title, time:this.time});
      }
      
    }
  },
  
  computed:{
    totalTime (){
      let total = 0;
      this.courses.forEach(function(curso) {
        total += parseInt(curso.time);
      });
      return total;      
    },
    
  }
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Curso Basico de Vue.js | Platzi</title>
  <link rel="stylesheet" href="./styles.css">
</head>
<body>
  <div id="app">
    <h1>Mis cursos</h1>

    <div id="container">
      <div id="agregarCurso">
        <h2>Listado de cursos</h2>
        
        <span>Título:</span><br>
        <input type="text" 
        placeholder="Escribe el nombre del curso"
        v-model="title">
        <br><br>
  
        <span>Horas:</span><br>
        <input type="number" v-model="time">
        <br><br>
  
        <button @click="addCourses()">Agregar curso</button>
  
      </div>
      <div id="listadoCursos">
        <h3>Listado de cursos</h3>
        <span v-if="courses.length==0">No hay cursos registrados</span>
        <div v-else>
          <table>
            <tr>
              <th>Materia</th>
              <th>Horas</th>
            </tr>
            <tr v-for="c in courses">
              <td >{{c.title}}</td>
              <td>{{c.time}}</td>
            </tr>
          </table>
          <br>
          <span>Total: {{totalTime}}</span>
        </div>
  
      </div>
  
    </div>

  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
  <script src="app.js"></script>
</body>
</html>

HTML

<!DOCTYPE html>
<html lang=“en”>
<head>
<meta charset=“UTF-8”>
<meta http-equiv=“X-UA-Compatible” content=“IE=edge”>
<meta name=“viewport” content=“width=device-width, initial-scale=1.0”>
<title>Project Nº01</title>
<link href=“https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css” rel=“stylesheet” integrity=“sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC” crossorigin=“anonymous”>

</head>
<body>

<div id="app">
<div class="container">
    <div class="row align-items-start">
      
        <span class="badge bg-primary mt-5">  <h2>Project de Courses de Platzi</h2> </span>
        
        <div class="col-6">
            <div class="alert alert-primary mt-5" role="alert">
                <h2 class="text-center"> Agregar Cursos</h2>
              </div>        
            <div class="row m-5" >
      
            <label for="title">NOMBRE DEL CURSO</label>
            <input type="text" id="title" v-model="title" >
         
            <label for="time">HORA X CURSO</label>
            <input type="number" id="time" v-model="time">

            <button type="button" class=" mt-4 btn btn-primary" @click="addCourse" >Agregar curso</button>
           
        </div>
        </div>

     <div class="col-6">
       
        <div class="alert alert-primary mt-5" role="alert">
            <h2 class="text-center"> Courses de Platzi</h2>
          </div>
          <p class="red text-center" v-show="!courses.length" >Aun no haz realizado cursos</p>
          <p class="green text-center" v-show="courses.length" >Ya tienes cursos !!!!</p>

          <table class="table">
            <thead>
                <tr>
                  <th scope="col">#</th>
                  <th scope="col">Name</th>
                  <th scope="col">Time Course</th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="(c,i) in courses">
                <th scope="row">{{i}}</th>
                <td>{{c.title}}</td>
                <td>{{c.time + "h"}}</td>  
              </tr>      
           
            </tbody>
          </table>

       
          <div class="alert alert-primary mt-5" role="alert">
                <h3> Tiempo invertido en educación : </h3>
                <h2 class="text-center">{{totalTime + " horas"}}</h2>
              </div>
      </div>
   
 </div>



</div>

</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

<script src="project.js"></script>

</body>
</html>

JS
const app = new Vue({
el : ‘#app’,

data(){
    return {
        courses : [],
        title : '',
        time :  0,



    }
}, 

computed: {
 
     
     totalTime(){
         if(!this.courses.length){ return 0}
     
     return this.courses.reduce((a,b) => a + parseInt(b.time),0)

     }

    
},

methods : {
    addCourse(){
        if(!this.title || !this.time){return  console.log("No registrastes nada")}
        this.courses.push({
            title: this.title , 
            time: this.time 
        })


        this.title=""
        this.time= 0
    }
    
    },

})