In Desarrollo Última actualizaciónated:
Comparte en:
Software de Jira es la herramienta de gestión de proyectos número uno utilizada por equipos ágiles para planificar, rastrear, lanzar y respaldar software excelente.

Aprende a crearate una aplicación Nuxt.

CRUD – Create, Leer, Actualizarate, Borrar

Supongo que ya conoces los fundamentos de Vue JS y/o eres un bit familiarizado con el marco. Nuxt JS es un marco robusto, construido sobre Vue JS. es esencialally Lo mismo que Vue JS. ¿Entonces por qué, Nuxt?

Para la mayoría de las personas, la decisión de utilizar Nuxt JS es habitual.ally por sus capacidades SSR.

¿Qué es SSR?

SSR es un abreviación para renderizado del lado del servidor.

Usúally, para la mayoría de las aplicaciones de una sola página (SPA), los archivos renderizados se inyectan automáticamente en el DOM después de que se haya cargado la página. Por lo tanto, los robots y los rastreadores de SEO encontrarán una página vacía al cargar la página. Sin embargo, para SSR, debido a su capacidad de renderizar previamente aplicaciones en el servidor antes de la página, los rastreadores de SEO pueden indexar fácilmente esa página. Además, posiblemente haga que la aplicación tenga un rendimiento aún mayor que un SPA normal.

NuxtJS ofrece a los desarrolladores la capacidad de crearate Aplicaciones SSR con facilidad. Las aplicaciones normales de Vue JS SPA también se pueden configurar para usar SSR, pero el process es algo engorroso y Nuxt JS proporciona un contenedor para manejar toda esa configuración. Además de SSR, Nuxt también proporciona una manera fácil de configurar su proyecto VueJS con más eficiencia.

Aunque Nuxt JS sigue siendo Vue JS, tiene algunas diferencias fundamentales en la estructura de su arquitectura de carpetas.

El objetivo de este artículo es que pueda crear una aplicación con Nuxt; por lo tanto, no vamos a profundizar en la arquitectura de carpetas de Nuxt, sin embargo, explicaré rápidamente algunos de los importantes que podríamos necesitar aquí.

Páginas

La carpeta de páginas es una de las diferencias fundamentales con respecto al Vue SPA normal. Representa la carpeta Vistas en la arquitectura Vue normal, además, en Nuxt, los archivos se crean.ated en la carpeta Páginas son automáticosally aprovisionado como ruta. Es decir, cuando creasate un archivo index.vue en la carpeta de páginas, que automáticamenteally se convierte en su ruta raíz, es decir, localhost:3000/.

Además, cuando creasate cualquier otro nombre de archivo.vue, se convierte en una ruta; crear about.vue le permite acceder a localhost:3000/about.

También puedes crearate una carpeta dentro de la carpeta Páginas. si creesate una carpeta llamada 'contacto' y dentro de esa carpeta, tiene email.vue, luego puede acceder a localhost:3000/contact/email. Es así de simple. De esta manera, no es necesario manually CREate un archivo router.js como lo haría típicoally hacer con Vue JS para crearate tus rutas.

Componentes

Sigue siendo más o menos lo mismo que con Vue JS, los componentes created no son automáticosally aprovisionados como rutas.

Estático

La carpeta estática reemplaza la carpeta pública en las aplicaciones regulares de Vue JS, funciona prácticamente de la misma manera. Los archivos aquí no se compilan; se sirven de la misma forma que se almacenan.

Puede leer todo sobre la arquitectura y la estructura en el Página de documentación de Nuxt JS.

Ahora, construyamos algo interesante ...

Creación de una aplicación de librería

Crearemos una aplicación de librería, donde un usuario puede agregar libros que ha leído a un c en particular.atesangrientos que les gustan. Se verá así.

Entonces, tendremos un diseño simple como el anterior, solo 3 columnas que contienen las diferentes secciones de los libros. Libros leídos recientemente, libros favoritos y sí, el mejor de los mejores libros (lo confieso, no sabía cómo llamar a esa sección, 🙂)

Entonces, el objetivo aquí es poder agregar el título, el autor y el nombre de un libro. description a una tarjeta en cualquiera de las secciones, editar libros ya agregados y eliminar un libro existente. No utilizaremos ninguna base de datos, por lo que todo sucede en el st.ate.

Primero, instalamos Nuxt:

npm install create-nuxt-app

En segundo lugar, después de instalar Nuxt, ahora puede crearate el proyecto con el comando,

create-nuxt-app bookStore

Elijo nombrar mi aplicación 'librería'; puedes nombrar algo más genial ^ _ ^

Luego, repasemos las indicaciones restantes, ingrese un description,

Nombre del autor, escriba un nombre o presione Intro para conservar los valores predeterminados

Seleccione un administrador de paquetes, con el que se sienta cómodo, ambos están bien

Seleccione un marco de interfaz de usuario. Para este proyecto, usaré Vuetify, por otra parte, cualquier marco de interfaz de usuario con el que se sienta cómodo funcionará bien.

Seleccione un marco de servidor personalizado; no necesitamos ninguno, no seleccionaré ninguno

Extra módulos, seleccione lo que desee o seleccione ambos, no los usaríamos para esta aplicación.

El pelaje es importante. Vayamos con ESLint.

Si bien las pruebas son importantes, no lo veremos hoy, por lo que ninguno

Modo de renderizado, sí, SSR.

Nota: Elegir SSR no significa que no obtengamos el beneficio de tener un SPA, la aplicación sigue siendo un SPA pero con SSR. La otra opción significa simplemente SPA y sin SSR.

Presiona enter y sigue adelante,

Y nuestro proyecto está creando,

Después creation, ahora podemos ir al directorio y ejecutar

yarn dev

si estás usando npm como su administrador de paquetes, use,

npm run dev

De forma predeterminada, la aplicación se ejecuta en localhost:3000. Visita el enlace en tu browser, y debería ver una página predeterminada de Nuxt.

Ahora comencemos con la creación de los componentes que necesitamos. Tendremos tarjetas que muestran la información de cada libro y tendremos un modal que contiene un formulario para ingresar la información del nuevo libro o editar la existente.

para crearate un componente, simplemente create un nuevo archivo en la carpeta de componentes. Aquí está el código para el componente de mi tarjeta.

// BookCard.vue

<template>
  <v-card class="mx-auto" max-width="400">
    <v-img src="https://cdn.vuetifyjs.com/images/cards/sunshine.jpg" height="200px"></v-img>
    <v-card-title>{{bookTitle}}</v-card-title>
    <v-card-subtitle>{{bookAuthor}}</v-card-subtitle>
    <v-card-text>{{bookDescription}}</v-card-text>
    <v-card-actions>
      <v-spacer></v-spacer>
      <slot name="button"></slot>
    </v-card-actions>
  </v-card>
</template>

<script>
export default {
  props: ["bookTitle", "bookAuthor", "bookDescription"]
};
</script>

Una explicación rápida de lo que se hace arriba. La imagen está codificada; No nos preocuparemos por eso por ahora. El título del libro, el autor del libro y el libro. descriptLos iones se transmiten a este componente desde la página principal como accesorios. Si no está familiarizado con los accesorios, imagínelos como puntos de entrada. Este componente puede ser popular.ated con datos.

Ahora al siguiente componente, el modal.

//BookModal.vue

<template>
  <v-dialog max-width="500px" v-model="open">
    <v-card class="p-5">
      <v-card-title>Add Books</v-card-title>
      <v-form>
        <v-select v-model="category" :items="categories" label="Select A Category"></v-select>
        <v-text-field v-model="title" label="Enter Book Title"></v-text-field>
        <v-text-field v-model="author" label="Enter Book Author"></v-text-field>
        <v-textarea v-model="description" label="Enter Book Description"></v-textarea>
      </v-form>
      <v-card-actions>
        <v-spacer></v-spacer>
        <v-btn @click.stop="saveBook" color="green">Add</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

Ahora, ese es el marcado para el modal; necesitamos crearate los modelos v como propiedades de datos; por lo tanto, agregaremos una etiqueta de script debajo deplate> etiqueta.

<script>
export default {
  data() {
    return {
      category: "",
      title: "",
      author: "",
      description: "",
    };
  },
}
</script>

Además, hay un 'Seleccione una Catemenú desplegable sangriento que espera 'catedatos de gories. Lo agregaremos a los datos.

<script>
export default {
  data() {
    return {
      open: false,
      category: "",
      title: "",
      author: "",
      description: "",
      categories: ["Recently read books", "Favourite books", "Best of the best"]
    };
  },
}
</script>

Ahora necesitamos una manera de toggle nuestro modal abrir y cerrar, por ahora, solo tendremos una propiedad de datos 'abierta' como se indicó anteriormente. Lo veremos de cerca a continuación.

Creemos rápidamenteate nuestra página de visualización donde tendremos tres cuadrículas/columnas, una para cada sección del libro. Llamemos a la página index.vue, consulte el código a continuación.

//index.vue
<template>
  <div>
    <v-row>
      <v-col md="4">
        <h2 class="text-center mb-5">Recently Read Books</h2>
      </v-col>
      <v-col md="4">
        <h2 class="text-center mb-5">Favourite Books</h2>
      </v-col>
      <v-col md="4">
        <h2 class="text-center mb-5">Best of the Best</h2>
      </v-col>
    </v-row>
    <BookModal />
  </div>
</template>

Ahora que tenemos nuestras cuadrículas, debemos agregar nuestro componente de tarjeta a cada cuadrícula, para cada libro agregado. Por lo tanto, importaremos nuestro componente BookCard.vue.

<template>
  <div>
    <v-row>
      <v-col md="4">
        <h2 class="text-center mb-5">Recently Read Books</h2>
        <v-row v-for="(item,index) in recentBooks" :key="index">
          <BookCard
            class="mb-5"
            :bookTitle="item.title"
            :bookAuthor="item.author"
            :bookDescription="item.description"
          >
            <template v-slot:button>
              <v-btn @click.stop="edit(item,index)">Edit</v-btn>
              <v-btn @click.stop="remove(item.category, index)">Remove</v-btn>
            </template>
          </BookCard>
        </v-row>
      </v-col>
      <v-col md="4">
        <h2 class="text-center mb-5">Favourite Books</h2>
        <v-row v-for="(item,index) in favouriteBooks" :key="index">
          <BookCard
            class="mb-5"
            :bookTitle="item.title"
            :bookAuthor="item.author"
            :bookDescription="item.description"
          >
            <template v-slot:button>
              <v-btn @click.stop="edit(item,index)">Edit</v-btn>
              <v-btn @click.stop="remove(item.category, index)">Remove</v-btn>
            </template>
          </BookCard>
        </v-row>
      </v-col>
      <v-col md="4">
        <h2 class="text-center mb-5">Best of the Best</h2>
        <v-row v-for="(item,index) in bestOfTheBest" :key="index">
          <BookCard
            class="mb-5"
            :bookTitle="item.title"
            :bookAuthor="item.author"
            :bookDescription="item.description"
          >
            <template v-slot:button>
              <v-btn @click.stop="edit(item,index)">Edit</v-btn>
              <v-btn @click.stop="remove(item.category, index)">Remove</v-btn>
            </template>
          </BookCard>
        </v-row>
      </v-col>
    </v-row>
  </div>
</template>

Ahora, hemos importado el componente BookCard y hemos vinculado sus accesorios a los resultados del bucle; esto garantiza que por cada entrada agregada a cualquiera de las secciones, haya una tarjeta created por ello. Además, en cada tarjeta incluiremos botones para editar o eliminar una tarjeta.

Ahora, necesitamos importar la tarjeta desde el script y definir las matrices que contendrán registros para cada uno de los c.ategories.

<script>
import BookCard from "@/components/BookCard";

export default {
  components: {
    BookCard,
  },
  data() {
    return {
      recentBooks: [],
      favouriteBooks: [],
      bestOfTheBest: []
    };
  },
};
</script>

A continuación, necesitamos tener un botón en el encabezado que abrirá el modal cada vez que necesitemos agregar libros. Haremos esto en el archivo 'default.vue'. Agregaremos el botón al encabezado predeterminado de la barra de aplicaciones.

<v-btn color="green" @click.stop="openModal">Add Books</v-btn>

A continuación, necesitamos un create el método openModal en la sección de script. En las aplicaciones Vue JS normales, hay un bus de eventos que le permite comunicarseate con otro componente e incluso pasar datos, en Nuxt JS, todavía hay un bus de eventos y aún puedes crearate lo mismo. Por lo tanto, usaremos un bus de eventos para pasar datos y abrir un modal en la página index.vue (que aún debemos importar) desde el archivo layout/default.vue.

Veamos como se hace.

para crearate un bus de eventos global, abra un archivo en el directorio raíz del proyecto, asígnele el nombre eventBus.js y pegue el código siguiente en él.

import Vue from 'vue'

export const eventBus = new Vue()

Sí, eso es todo. Ahora podemos usarlo.

<script>
import { eventBus } from "@/eventBus";
methods: {
    openModal() {
      eventBus.$emit("open-add-book-modal");
    }
  }
</script>

A continuación, volveremos a nuestro componente BookModal y escucharemos cuando eventBus emite 'open-add-book-modal'. Agregaremos esto a la sección del script.

import { eventBus } from "@/eventBus";

created() {
    eventBus.$on("open-add-book-modal", this.open = true);
  },

Ahora podemos abrir y cerrar nuestro modal, pero aún no agrega ningún libro. Agreguemos un método a nuestro Modal para que guarde lo que se agrega al st.ate (recuerde que no estamos haciendo uso de ninguna base de datos ni almacenamiento local). Agregamos esto al lado de 'created()'

methods: {
    saveBook() {
      let cardData = {
        title: this.title,
        author: this.author,
        description: this.description,
        category: this.category
      };
      eventBus.$emit("save-book", cardData);
      this.open = false;
    }
  }

A continuación, necesitamos una manera de repoblarate el modal cuando estamos editando datos de cualquiera de las tarjetas. Así que hagamos algunos ajustes al 'cre'.ated()'

created() {
    eventBus.$on("open-add-book-modal", data => {
      if (data) {
        this.category = data.category;
        this.title = data.title;
        this.author = data.author;
        this.description = data.description;
      }
      this.open = true;
    });
  },

Ahora, el BookModal se ve así como un todo,

//BookModal.vue


<template>
  <v-dialog max-width="500px" v-model="open">
    <v-card class="p-5">
      <v-card-title>Add Books</v-card-title>
      <v-form>
        <v-select v-model="category" :items="categories" label="Select A Category"></v-select>
        <v-text-field v-model="title" label="Enter Book Title"></v-text-field>
        <v-text-field v-model="author" label="Enter Book Author"></v-text-field>
        <v-textarea v-model="description" label="Enter Book Description"></v-textarea>
      </v-form>
      <v-card-actions>
        <v-spacer></v-spacer>
        <v-btn @click.stop="saveBook" color="green">Add</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script>
import { eventBus } from "@/eventBus";
export default {
  data() {
    return {
      open: false,
      category: "",
      title: "",
      author: "",
      description: "",
      categories: ["Recently read books", "Favourite books", "Best of the best"]
    };
  },
  created() {
    eventBus.$on("open-add-book-modal", data => {
      if (data) {
        this.category = data.category;
        this.title = data.title;
        this.author = data.author;
        this.description = data.description;
      }
      this.open = true;
    });
  },
  methods: {
    saveBook() {
      let cardData = {
        title: this.title,
        author: this.author,
        description: this.description,
        category: this.category
      };
      eventBus.$emit("save-book", cardData);
      this.open = false;
    }
  }
};
</script>

A continuación, ahora podemos volver a la página index.vue para importar el componente BookModal. Agregaremos esto a la sección del script.

<script>
import BookCard from "@/components/BookCard";
import BookModal from "@/components/BookModal";
import { eventBus } from "@/eventBus";

export default {
  components: {
    BookCard,
    BookModal
  },
  data() {
    return {
      recentBooks: [],
      favouriteBooks: [],
      bestOfTheBest: []
    };
  },
</script>

Además, en el cuerpo, agregaremos,

<BookModal/>

Necesitamos métodos para editar y eliminar una tarjeta. en el tiempoplatAntes, ya pasé los métodos de edición y eliminación a los botones como se muestra a continuación, comowise, pasé los argumentos necesarios para cada método.

<template v-slot:button> <v-btn @click.stop="edit(item,index)">Edit</v-btn> <v-btn @click.stop="remove(item.category, index)">Remove</v-btn> </template>

vamos a crearate los métodos.

methods: {
    remove(category, index) {
      if (category === "Recently read books") {
        this.recentBooks.splice(index, 1);
      }
      if (category === "Favourite books") {
        this.favouriteBooks.splice(index, 1);
      }
      if (category === "Best of the best") {
        this.bestOfTheBest.splice(index, 1);
      }
    },
    edit(item, index) {
      if (item.category === "Recently read books") {
        eventBus.$emit("open-add-book-modal", item);
        this.recentBooks.splice(index, 1);
      }
      if (item.category === "Favourite books") {
        eventBus.$emit("open-add-book-modal", item);
        this.favouriteBooks.splice(index, 1);
      }
      if (item.category === "Best of the best") {
        eventBus.$emit("open-add-book-modal", item);
        this.bestOfTheBest.splice(index, 1);
      }
    }
  }

Recuerde, BookModal está emitiendo, y un evento llamado save-book, necesitamos un oyente para ese evento aquí.

created() {
    eventBus.$on("save-book", cardData => {
      if (cardData.category === "Recently read books") {
        this.recentBooks.push(cardData);
      }
      if (cardData.category === "Favourite books") {
        this.favouriteBooks.push(cardData);
      }
      if (cardData.category === "Best of the best") {
        this.bestOfTheBest.push(cardData);
      }
    });
  },

Ahora, en un vistazo completo, nuestra página index.vue se ve así

<template>
  <div>
    <v-row>
      <v-col md="4">
        <h2 class="text-center mb-5">Recently Read Books</h2>
        <v-row v-for="(item,index) in recentBooks" :key="index">
          <BookCard
            class="mb-5"
            :bookTitle="item.title"
            :bookAuthor="item.author"
            :bookDescription="item.description"
          >
            <template v-slot:button>
              <nuxt-link :to="`/books/${item.title}`">
                <v-btn>View</v-btn>
              </nuxt-link>
              <v-btn @click.stop="edit(item,index)">Edit</v-btn>
              <v-btn @click.stop="remove(item.category, index)">Remove</v-btn>
            </template>
          </BookCard>
        </v-row>
      </v-col>
      <v-col md="4">
        <h2 class="text-center mb-5">Favourite Books</h2>
        <v-row v-for="(item,index) in favouriteBooks" :key="index">
          <BookCard
            class="mb-5"
            :bookTitle="item.title"
            :bookAuthor="item.author"
            :bookDescription="item.description"
          >
            <template v-slot:button>
              <v-btn @click.stop="edit(item,index)">Edit</v-btn>
              <v-btn @click.stop="remove(item.category, index)">Remove</v-btn>
            </template>
          </BookCard>
        </v-row>
      </v-col>
      <v-col md="4">
        <h2 class="text-center mb-5">Best of the Best</h2>
        <v-row v-for="(item,index) in bestOfTheBest" :key="index">
          <BookCard
            class="mb-5"
            :bookTitle="item.title"
            :bookAuthor="item.author"
            :bookDescription="item.description"
          >
            <template v-slot:button>
              <v-btn @click.stop="edit(item,index)">Edit</v-btn>
              <v-btn @click.stop="remove(item.category, index)">Remove</v-btn>
            </template>
          </BookCard>
        </v-row>
      </v-col>
    </v-row>
    <BookModal />
  </div>
</template>

<script>
import BookCard from "@/components/BookCard";
import BookModal from "@/components/BookModal";
import { eventBus } from "@/eventBus";

export default {
  components: {
    BookCard,
    BookModal
  },
  data() {
    return {
      recentBooks: [],
      favouriteBooks: [],
      bestOfTheBest: []
    };
  },
  created() {
    eventBus.$on("save-book", cardData => {
      if (cardData.category === "Recently read books") {
        this.recentBooks.push(cardData);
        this.recentBooks.sort((a, b) => b - a);
      }
      if (cardData.category === "Favourite books") {
        this.favouriteBooks.push(cardData);
        this.favouriteBooks.sort((a, b) => b - a);
      }
      if (cardData.category === "Best of the best") {
        this.bestOfTheBest.push(cardData);
        this.bestOfTheBest.sort((a, b) => b - a);
      }
    });
  },
  methods: {
    remove(category, index) {
      if (category === "Recently read books") {
        this.recentBooks.splice(index, 1);
      }
      if (category === "Favourite books") {
        this.favouriteBooks.splice(index, 1);
      }
      if (category === "Best of the best") {
        this.bestOfTheBest.splice(index, 1);
      }
    },
    edit(item, index) {
      if (item.category === "Recently read books") {
        eventBus.$emit("open-add-book-modal", item);
        this.recentBooks.splice(index, 1);
      }
      if (item.category === "Favourite books") {
        eventBus.$emit("open-add-book-modal", item);
        this.favouriteBooks.splice(index, 1);
      }
      if (item.category === "Best of the best") {
        eventBus.$emit("open-add-book-modal", item);
        this.bestOfTheBest.splice(index, 1);
      }
    }
  }
};
</script>

Si llegaste tan lejos, ¡¡¡Buen trabajo !!! ¡Usted es maravilloso!

Como se mencionó anteriormente, cada archivo .vue creaated en la carpeta de páginas es automáticoally aprovisionado como una ruta, comowise, para cada carpeta created dentro de la carpeta de páginas. Esto no sólo se aplica a las páginas estáticas, sino que también se pueden crear páginas dinámicas.ate¡Dé esta manera también!

A ver cómo.

Usando nuestro proyecto actual, digamos que queremos agregar una página dinámica para todas las tarjetas de libros con un botón de visualización para ver más detalles sobre un libro.

Agreguemos rápidamente un botón de vista y usemos un <nuxt-link> para visitar la página. Si, <nuxt-link> reemplaza <router-link> y funciona.

<nuxt-link :to="`/${item.title}`">
                <v-btn>View</v-btn>
              </nuxt-link>

A continuación, creamosate una carpeta dinámica anteponiendo al nombre un guión bajo. es decir, _title y dentro de esa carpeta, tendremos un archivo index.vue que se representa cuando visitamos esa ruta.

Solo para demostración, solo accederemos a la propiedad params dentro del archivo.

// _title/index.vue

<template>
  <h1>{{$route.params.title}}</h1>
</template>

Ahora, al hacer clic en ver, se abre otra página donde podemos ver el título que hemos pasado por la ruta. Esto se puede desarrollar para hacer lo que queramos en lo que respecta a las páginas dinámicas.

¡Eso es todo por esta lección!

El código completo para esto se puede encontrar en este repositorio. Le invitamos a contribuir al código. Si está interesado en dominar el marco, le sugiero esto Curso Udemy.

Comparte en:
  • Idris Leyal
    Autor
    Idris es ingeniero de software, con experiencia en redes informáticas.

Gracias a nuestros patrocinadores

Más lecturas interesantes sobre el desarrollo

Impulse su negocio

Algunas de las herramientas y servicios para ayudar a su negocio grow.
  • La herramienta de conversión de texto a voz que utiliza IA para generarate Voces realistas parecidas a las humanas.

    Intente Murf AI
  • Web scraping, proxy residencial, administrador de proxy, desbloqueador web, rastreador de motores de búsqueda y todo lo que necesita para recopilar datos web.

    Prueba Brightdata
  • Monday.com es un sistema operativo de trabajo todo en uno para ayudarlo a administrar proyectos, tareas, trabajo, ventas, CRM, operaciones, workflows, y más.

    Intente Monday
  • Intruder es un escáner de vulnerabilidades en línea que encuentra debilidades de ciberseguridad en su infraestructura, para evitar costosas filtraciones de datos.

    Intente Intruder