Programación, Tecnología y Más...

Programación, Tecnología y Más...

Todo Bootstrap 5 Vue 3

En este artículo estaremos creando el famoso todo pero lo haremos usando bootstrap 5 y vue 3, también estaremos usando localstorage para poder persistir y administrar las tareas.

El resultado final de nuestra aplicación será el siguiente

TODO APP


Lo primero que haremos será instalar la última versión de bootstrap 


npm install --save @popperjs/core bootstrap@next
En nuestro main.js debemos importar bootstrap

import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";
Dentro de la carpeta components crearemos un nuevo componente llamado Header.vue que como su nombre lo indica será la parte del header de nuestra aplicación y el encargado de mostrar un diálogo en donde el usuario podrá ingresar su nombre

<template>
  <h4 className="bg-primary text-white text-center p-4">
    Todo App - {{name}}
  </h4>
</template>

<script>
import { onMounted, ref } from "vue";

export default {
  name: "Header",
  setup() {
    const  name = ref('');
    onMounted(() => {
      const person = prompt("Please enter your name:");
      if (person == null || person == "") {
        name.value = "Leo Messi";
      } else {
        name.value =  person ;
      }
    });
    return {
      name
    };
  },
};
</script>
Creamos otro componente llamado Tasks.vue que será el encargado de listar todas las tareas ingresadas por los usuarios, este componente también será el encargado de poder cambiar de estado las tareas a terminadas y eliminarlas

<template>
  <div class="container" v-if="tasks.length > 0">
    <div class="row">
      <div class="col bg-danger text-white">
        Pending : {{tasks.filter(t => t.done == false).length}}
      </div>
      <div class="col bg-success text-white">
        Completed : {{tasks.filter(t => t.done == true).length}}
      </div>
    </div>
  </div>
  <div v-for="(item, index) in tasks" :key="index" class="pt-2">
    <div
      :class="['alert', item.done ? 'alert-success' : 'alert-danger']"
      role="alert"
    >
      <div class="d-flex justify-content-between align-items-center">
        <div>
          <h5>{{ item.name }}</h5>
        </div>
        <div>
          <button
            type="button"
            class="btn btn-outline-success bt-sm mx-3"
            @click="editTask(index)"
          >
            <i class="bi bi-check-lg"></i>
          </button>
          <button
            type="button"
            class="btn btn-outline-danger bt-sm"
            @click="deleteTask(index)"
          >
            <i class="bi bi-x-lg"></i>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Tasks",
  props: {
    tasks: {
      type: Array,
      default: () => [],
    },
  },

  emits: ["editTask", "deleteTask"],
  setup(props, { emit }) {
    const editTask = (index) => {
      emit("editTask", index);
    };

    const deleteTask = (index) => {
      emit("deleteTask", index);
    };
    return {
      editTask,
      deleteTask,
    };
  },
};
</script>

<style lang="scss" scoped></style>
Creamos un último componente llamado AddTask.vue que será el encargado de poder agregar nuevas tareas

<template>
  <div class="input-group my-4">
    <input
      type="text"
      class="form-control"
      placeholder="run"
      v-model="task"
      @keyup.enter="addTask"
    />
    <button class="btn btn-primary" type="button" @click="addTask">
<i class="bi bi-plus-lg"></i> 
    </button>
  </div>
</template>

<script>
import { ref } from "vue";

export default {
  name: "AddTask",

  emits: ["addTask"],
  setup(props, { emit }) {
    const task = ref('');

    const addTask = () => {
      const newTask = {
          name: task.value,
          done: false,
      }
      emit("addTask", newTask);
      task.value = "";
    };
    return {
        task,
        addTask,
    };
  },
};
</script>

<style lang="scss" scoped></style>
Ahora dentro de App.vue  usamos los componentes creados anteriormente y agregamos la funcionalidad para poder persistir la información en localstorage

<template>
  <Header />
  <div class="container">
    <AddTask @addTask="addTask" />
    <Tasks :tasks="tasks" @editTask="editTask" @deleteTask="deleteTask" />
  </div>
</template>

<script>
import Header from "@/components/Header.vue";
import Tasks from "@/components/Tasks.vue";
import AddTask from "@/components/AddTask.vue";
import { onMounted, ref } from "vue";

export default {
  name: "App",
  components: {
    Header,
    Tasks,
    AddTask,
  },

  setup() {
    const tasks = ref([]);

    onMounted(() => {
      let dataLocalStorage = JSON.parse(localStorage.getItem("tasks"));
      if (dataLocalStorage === null) {
        tasks.value = [];
      } else {
        tasks.value = dataLocalStorage;
      }
    });

    const updateLocalStorage = () => {
      localStorage.setItem("tasks", JSON.stringify(tasks.value));
    };

    const addTask = (task) => {
      tasks.value.push({
        name: task.name,
        done: task.done,
      });
      console.log(tasks.value);
      updateLocalStorage();
    };

    const editTask = (index) => {
      tasks.value[index].done = true;
      updateLocalStorage();
    };

    const deleteTask = (index) => {
      tasks.value.splice(index, 1);
      updateLocalStorage();
    };

    return {
      updateLocalStorage,
      tasks,
      addTask,
      editTask,
      deleteTask,
    };
  },
};
</script>

<style></style>

TODO APP

Puedes ver la aplicación funcionando https://todo-bootstrap-vue3.web.app 

puedes descargar el código desde este repositorio

si quieren donarme para una café lo pueden hacer aqui.

Hasta la próxima.

Saludos desde El Salvador...

Publicar un comentario

0 Comentarios