Overview
Este tutorial te guía a través de la creación de una aplicación Nuxt que utiliza Vue e integra MongoDB. Nuxt es un framework de Vue que proporciona rutas basadas en archivos, renderizado en el lado del servidor y rutas API integradas a través de su motor de servidor Nitro. Nuxt combinado con Vue te permite compilar aplicaciones completas sin un servidor back-end independiente.
La aplicación en este tutorial contiene las siguientes capas:
Capa de base de datos: MongoDB proporciona almacenamiento y recuperación de datos
Capa de servidor: las rutas del servidor de Nuxt se encargan de la lógica de la API y de las interacciones con la base de datos.
Capa de presentación: Vue implementa la interfaz de usuario con enlace de datos reactivo
¿Por qué usar MongoDB con Nuxt y Vue?
Nuxt se basa en Vue para ofrecer un framework full-stack con un runtime de Node.js para rutas del servidor, lo que lo convierte en el complemento perfecto para el driver MongoDB Node.js. Puedes conectarte a MongoDB directamente desde las rutas de tu servidor Nuxt o utilidades del lado del servidor y devolver documentos a tus componentes Vue sin mantener un servicio back-end separado o una capa de API.
La estructura flexible de documentos de MongoDB se adapta fácilmente a los objetos de JavaScript. Como resultado, puedes trabajar sin problemas con los datos de MongoDB en tus componentes de Vue, ya sea que estés usando la API de opciones o la API de composición. Se pueden pasar los documentos obtenidos de MongoDB directamente a los componentes y plantillas, lo que reduce la necesidad de una transformación de datos compleja o de una capa adicional de mapeo objeto-relacional (ORM).
El renderizado del lado del servidor (SSR) de Nuxt y las utilidades de obtención de datos permiten query MongoDB en el servidor antes de renderizar las páginas. Esto te permite hidratar tus componentes Vue con datos listos para usar, mejorando el rendimiento percibido y el SEO para aplicaciones basadas en datos.
Tutorial de inicio rápido
Este tutorial te muestra cómo compilar una aplicación web utilizando Nuxt y Vue. La aplicación accede a datos de muestra de restaurantes, query los datos y muestra los resultados en un sitio hosteado localmente. El tutorial también incluye instrucciones para conectarte a un clúster de MongoDB alojado en MongoDB Atlas y para acceder y mostrar datos de tu base de datos.
Tip
Si prefieres conectarte a MongoDB usando el driver de Node.js sin Nuxt, consulta la Guía Comenzar con el driver de Node.js.
Configurar el proyecto
Siga los pasos de esta sección para instalar las dependencias del proyecto, crear un clúster de Atlas y configurar los directorios de la aplicación.
Verifique los requisitos previos
Para crear la aplicación Quick Start, instala el siguiente software en tu entorno de desarrollo:
Requisito previo | notas |
Utiliza la versión 20 o posterior. | |
Editor de código | Este tutorial utiliza Visual Studio Code, pero puede utilizar el editor de su preferencia. |
Aplicación de terminal y shell | Para usuarios de macOS o Linux, utiliza la Terminal o una aplicación similar. Para los usuarios de Windows, utilicen PowerShell. |
Crea un clúster de MongoDB Atlas
O MongoDB Atlas é um serviço de banco de dados na nuvem totalmente gerenciado que hospeda as implementações do MongoDB. Si no tienes una implementación de MongoDB, puedes crear un clúster de MongoDB de forma gratuita (no se requiere tarjeta de crédito) completando el tutorial Primeros pasos en MongoDB.
Tip
Asegúrese de que el sample_restaurants El conjunto de datos se carga en tu clúster. Este tutorial query datos de ese conjunto de datos. Para aprender a cargar el conjunto de datos sample_restaurants en tu clúster, consulta el tutorial de Introducción a MongoDB.
Para conectarte a tu clúster de MongoDB, debes usar un URI de conexión. Para saber cómo recuperar tu URI de conexión, consulta la sección Agrega tu cadena de conexión del tutorial Primeros pasos de MongoDB.
Tip
Guarde su cadena de conexión de MongoDB Atlas en una ubicación segura. Lo agregarás a tu archivo .env en un paso posterior.
Instalar Nuxt y Vue
Usa la CLI oficial de Nuxt para iniciar un nuevo proyecto Nuxt con Vue. Abre tu terminal y navega hasta el directorio del proyecto que deseas.
Ejecuta el comando de inicialización:
npm create nuxt@latest
Indicaciones de configuración
La interfaz CLI te solicita configurar tu proyecto. Utiliza las siguientes respuestas:
Mensaje del sistema: Necesita instalar los siguientes paquetes: create-nuxt@latest-number. ¿La instalación puede continuar?
Respuesta: escribe
yy pulsa Intro.Mensaje: ¿Qué plantilla te gustaría utilizar?
Respuesta: Seleccione
minimal - Minimal setup for Nuxt 4 (recommended).Pregunta: ¿Dónde te gustaría crear tu proyecto?
Respuesta: Presiona
Enterpara aceptar el directorio por defecto o ingresa una ruta diferente.Mensaje: ¿Qué gestor de paquetes te gustaría usar?
Respuesta: Seleccione
npm.Solicitud: ¿Inicializar el repositorio git?
Respuesta: Seleccione
YesoNoen función de sus preferencias.Sugerencia: ¿Le gustaría instalar alguno de los módulos oficiales?
Respuesta: Seleccione
No.
Instale las dependencias
Navegue hasta el directorio de su proyecto e instale el controlador MongoDB, los iconos Lucide, Tailwind y las dependencias relacionadas ejecutando los siguientes comandos:
npm install mongodb lucide-vue-next npm install -D @types/node @nuxtjs/tailwindcss
Puede ignorar de forma segura cualquier advertencia sobre paquetes obsoletos de la instalación de Tailwind.
Configurar el Back-End
Después de configurar la estructura del proyecto, sigue los pasos de esta sección para configurar el back-end.
Configure su variable de entorno
Crea un archivo .env en la raíz de tu proyecto para almacenar de forma segura tu URI de conexión ejecutando el siguiente comando en la raíz de tu proyecto:
touch .env
Abre el archivo .env y añade tu URI de conexión:
MONGODB_URI=<Your Connection URI>
Nota
Reemplaza <Your Connection URI> con el URI de conexión que has recibido de MongoDB Atlas.
Actualiza tu configuración de Nuxt
Abre el archivo nuxt.config.ts en la raíz de tu proyecto y reemplázalo con el siguiente código para cargar las variables de entorno y configurar el módulo Tailwind CSS:
// https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ compatibilityDate: '2025-07-15', devtools: { enabled: true }, future:{ compatibilityVersion: 4, }, runtimeConfig:{ // Server-side only config. Not exposed to the client mongoURI: process.env.MONGODB_URI, }, css:['@/assets/css/main.css'], modules: ['@nuxtjs/tailwindcss'], })
El archivo nuxt.config.ts carga variables de entorno desde el archivo .env y configura el soporte de Tailwind para el estilo de tus componentes Vue.
Crear una conexión a la base de datos
Ejecuta los siguientes comandos en la raíz de tu proyecto para crear un archivo de utilidad que contenga la lógica de conexión a MongoDB:
mkdir -p server/utils touch server/utils/mongodb.ts
Abre el archivo server/utils/mongodb.ts y añade el siguiente código:
import { MongoClient, type Db } from "mongodb"; let cachedClient: MongoClient | null = null; let cachedDb: Db | null = null; export async function connectToDatabase(){ if (cachedClient && cachedDb){ return { client: cachedClient, db: cachedDb }; } const config = useRuntimeConfig(); const uri = config.mongoURI; if (!uri){ throw new Error("Please define the MONGO_URI environment variable inside .env"); } const client = new MongoClient(uri); await client.connect(); const db = client.db("sample_restaurants"); cachedClient = client; cachedDb = db; console.log("Connected to MongoDB Atlas"); return { client, db }; }
Este código crea un cliente reutilizable de MongoDB que se conecta a tu clúster de Atlas usando el URI de conexión almacenado en tu variable de entorno. El cliente se conecta a la base de datos sample_restaurants, que contiene información sobre restaurantes en la ciudad de Nueva York.
Crear ruta de restaurante
Las rutas del servidor Nuxt gestionan las solicitudes de API y interactúan con la base de datos. Ejecuta los siguientes comandos en la raíz de tu proyecto para crear una ruta de servidor para obtener datos de restaurantes:
mkdir -p server/api/restaurants touch server/api/restaurants/index.get.ts
Abre el archivo server/api/restaurants/index.get.ts y añade el siguiente código:
import { connectToDatabase } from "~~/server/utils/mongodb"; export default defineEventHandler(async () =>{ const { db } = await connectToDatabase(); const collection = db.collection("restaurants"); const restaurants = await collection .find({}) .limit(50) .project({ name: 1, borough: 1, cuisine: 1, grades: 1}) .toArray(); return restaurants.map((doc) => ({ ...doc, _id: doc._id.toString(), })) })
Este archivo define una ruta de servidor que hace query a la colección restaurants. Recupera los primeros 50 documentos de restaurantes y los devuelve como una respuesta JSON.
Crear una ruta de restaurantes filtrada
Ejecute el siguiente comando en la raíz de su proyecto para crear el nuevo archivo de ruta:
touch server/api/restaurants/browse.get.ts
Abre el archivo server/api/restaurants/browse.get.ts y añade el siguiente código:
import { connectToDatabase } from '~~/server/utils/mongodb' export default defineEventHandler(async () => { const { db } = await connectToDatabase(); const collection = db.collection("restaurants"); // Filter: Queens borough + name contains "Moon" (case-insensitive) const query = { borough: 'Queens', name: { $regex: 'Moon', $options: 'i' }, } const restaurants = await collection .find(query) .project({ name: 1, borough: 1, cuisine: 1, grades: 1 }) .toArray() return restaurants.map((doc) => ({ ...doc, _id: doc._id.toString(), })) })
Este archivo define una ruta de servidor que consulta la base de datos sample_restaurants en Queens para restaurantes cuyos nombres contengan la palabra Moon y devuelve los documentos coincidentes como una respuesta JSON.
Configure el Front End
Después de configurar el back end, sigue los pasos de esta sección para configurar la capa de presentación de tu aplicación.
Crea un archivo main.css
Ejecute el siguiente comando en la raíz de su proyecto para crear un archivo CSS principal para los estilos globales:
mkdir -p app/assets/css touch app/assets/css/main.css
Abre el archivo app/assets/css/main.css y añade el siguiente código:
@tailwind base; @tailwind components; @tailwind utilities;
Este archivo importa directivas de Tailwind CSS que generan clases utilitarias para el estilo de tu aplicación. Tailwind proporciona un conjunto completo de clases precompiladas para el diseño, el espaciado, los colores y la tipografía, sin necesidad de CSS personalizado.
Cree un componente de lista de restaurantes
Ejecuta los siguientes comandos en la raíz de tu proyecto para crear un componente de Vue que muestre los datos de un restaurante:
mkdir -p app/components touch app/components/RestaurantList.vue
Abre el archivo app/components/RestaurantList.vue y añade el siguiente código:
<script setup lang="ts"> import { computed } from 'vue' import { MapPin, Utensils, ChevronRight } from 'lucide-vue-next' // Type definitions interface Grade { grade?: string score?: number } interface Restaurant { _id: string name: string borough?: string cuisine?: string grades?: Grade[] } // Determine endpoint based on current route const route = useRoute() const isBrowse = computed(() => route.path === '/browse') const endpoint = computed(() => isBrowse.value ? '/api/restaurants/browse' : '/api/restaurants' ) // Fetch data using Nuxt's useFetch composable // Automatically refetches when endpoint changes const { data: restaurants } = await useFetch<Restaurant[]>(endpoint, { watch: [endpoint], default: () => [], }) // Dynamic page content const pageTitle = computed(() => isBrowse.value ? 'Hidden Gems in Queens' : 'All Restaurants' ) const pageSubtitle = computed(() => isBrowse.value ? "Filtered by: Borough 'Queens' & Name contains 'Moon'" : 'Explore our complete directory of local favorites' ) // Deterministic gradient based on name length const getGradient = (name: string) => { const gradients = [ 'from-orange-400 to-pink-500', 'from-blue-400 to-indigo-500', 'from-green-400 to-emerald-500', 'from-purple-400 to-fuchsia-500', ] return gradients[name.length % gradients.length] } </script> <template> <div class="max-w-6xl mx-auto px-4 py-8"> <!-- Header --> <div class="mb-8"> <h3 class="text-3xl font-bold text-gray-800"> {{ pageTitle }} </h3> <p class="text-gray-500 mt-2"> {{ pageSubtitle }} </p> </div> <!-- Restaurant Grid --> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> <div v-for="restaurant in restaurants" :key="restaurant._id" class="group bg-white rounded-2xl border border-gray-100 shadow-sm hover:shadow-xl hover:-translate-y-1 transition-all duration-300 overflow-hidden flex flex-col" > <!-- Gradient Header --> <div :class="[ 'h-32 bg-gradient-to-br p-6 flex items-end relative', getGradient(restaurant.name) ]" > <span class="absolute top-4 right-4 bg-white/20 backdrop-blur-md text-white text-xs font-bold px-2 py-1 rounded-full border border-white/30"> Grade {{ restaurant.grades?.[0]?.grade ?? 'N/A' }} </span> <h3 class="text-white text-xl font-bold drop-shadow-md line-clamp-2"> {{ restaurant.name }} </h3> </div> <!-- Card Body --> <div class="p-5 flex-1 flex flex-col"> <div class="flex items-center justify-between mb-4"> <span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md text-xs font-medium bg-green-50 text-green-700 border border-green-100"> <Utensils class="w-3 h-3" /> {{ restaurant.cuisine ?? 'Unknown' }} </span> <div class="flex items-center text-gray-400 text-xs font-medium"> <MapPin class="w-3 h-3 mr-1" /> {{ restaurant.borough ?? 'Unknown' }} </div> </div> <div class="mt-auto pt-4 border-t border-gray-50 flex items-center justify-between text-sm"> <span class="text-gray-400"> Score: {{ restaurant.grades?.[0]?.score ?? 0 }} </span> <button class="text-indigo-600 font-semibold group-hover:underline flex items-center gap-1"> View Menu <ChevronRight class="w-4 h-4" /> </button> </div> </div> </div> </div> <!-- Empty State --> <div v-if="restaurants?.length === 0" class="text-center py-12 text-gray-500"> <p>No restaurants found.</p> <p class="text-sm mt-2">Check your MongoDB connection and ensure the sample_restaurants database is loaded.</p> </div> </div> </template>
Este componente de Vue recupera los datos del restaurante desde tu ruta del servidor Nuxt y los muestra en una cuadrícula responsiva. Adapta dinámicamente el endpoint de la API y el contenido de la página según la ruta actual, mostrando todos los restaurantes o resultados filtrados.
Crea el componente de la barra de navegación
Ejecute el siguiente comando en la raíz de su proyecto para crear un componente Vue para la barra de navegación:
touch app/components/Navbar.vue
Abre el archivo app/components/Navbar.vue y añade el siguiente código:
<template> <nav class="flex justify-between items-center mb-6 bg-white shadow-md px-6 py-4 rounded-lg"> <NuxtLink to="/"> <img alt="MongoDB logo" class="h-10" src="https://d3cy9zhslanhfa.cloudfront.net/media/3800C044-6298-4575-A05D5C6B7623EE37/4B45D0EC-3482-4759-82DA37D8EA07D229/webimage-8A27671A-8A53-45DC-89D7BF8537F15A0D.png" /> </NuxtLink> <div class="flex gap-4"> <NuxtLink to="/" class="px-4 py-2 rounded-lg text-sm font-medium transition-colors" :class="$route.path === '/' ? 'bg-indigo-100 text-indigo-700' : 'text-gray-600 hover:bg-gray-100'" > All Restaurants </NuxtLink> <NuxtLink to="/browse" class="px-4 py-2 rounded-lg text-sm font-medium transition-colors" :class="$route.path === '/browse' ? 'bg-indigo-100 text-indigo-700' : 'text-gray-600 hover:bg-gray-100'" > Browse Filtered </NuxtLink> </div> </nav> </template>
Este componente de Vue renderiza la barra de navegación sobre los resultados del restaurante y contiene el All Restaurants y Filtered Restaurants enlaces. Estos permiten navegar entre las rutas.
Crea la página de índice
Ejecuta el siguiente comando en la raíz de tu proyecto para crear una página de índice para la aplicación:
mkdir -p app/pages touch app/pages/index.vue
Abre el archivo app/pages/index.vue y añade el siguiente código:
<template> <RestaurantList /> </template>
Este archivo muestra los resultados de la ruta del servidor index.get.ts utilizando los componentes RestaurantList y Navbar.
Cree la página de restaurantes filtrados
Ejecute el siguiente comando en la raíz de su proyecto para crear una nueva página de Vue que muestre datos de restaurantes filtrados:
touch app/pages/browse.vue
Abre el archivo app/pages/browse.vue y añade el siguiente código:
<template> <RestaurantList /> </template>
Este archivo muestra los resultados de una query filtrada en la base de datos sample_restaurants que retorna todos los restaurantes en Queens cuyos nombres contienen la palabra Moon. También utiliza los componentes RestaurantList y Navbar para construir la página.
Verifica tu estructura de archivos
Antes de continuar, asegúrate de que tu árbol de archivos coincida estrechamente con la estructura a continuación. Puedes ignorar de forma segura cualquier archivo de proyecto adicional.
your-project-directory/ ├── .env <-- Environment variable file ├── app/ │ ├── app.vue <-- Main application component │ ├── assets/ │ │ └── css/ │ │ └── main.css <-- Tailwind config │ ├── components/ │ │ ├── Navbar.vue <-- All restaurants and filtered restaurants links │ │ └── RestaurantList.vue <-- Container for restaurant data │ └── pages/ │ ├── browse.vue <-- Filtered restaurants page │ └── index.vue <-- All restaurants page ├── server/ │ ├── api/ │ │ └── restaurants/ │ │ ├── browse.get.ts <-- Filtered restaurants route │ │ └── index.get.ts <-- All restaurants route │ └── utils/ │ └── mongodb.ts <-- MongoDB connection utility ├── nuxt.config.ts <-- Nuxt configuration file └── package.json
Ejecutar la aplicación
Realiza los siguientes pasos para iniciar el servidor y ver los datos de restaurante renderizados.
Iniciar el servidor
Ejecute el siguiente comando en la raíz de su proyecto para iniciar el servidor de desarrollo:
npm run dev
Si es exitoso, el comando muestra la siguiente información en la terminal:
Nuxt 4.2.2 (with Nitro 2.13.1, Vite 7.3.1 and Vue 3.5.27) Local: http://localhost:3000/ Network: use --host to expose Using default Tailwind CSS file DevTools: press Shift + Option + D in the browser (v3.1.1) Vite client built in 22ms Vite server built in 19ms Nuxt Nitro server built in 247ms Vite server warmed up in 0ms Vite client warmed up in 1ms Connected to MongoDB Atlas
¡Felicidades por completar el tutorial de inicio rápido!
Una vez que completes estos pasos, tendrás una aplicación Nuxt y Vue que se conecta a tu implementación de MongoDB, ejecuta queries sobre datos de restaurantes de muestra y renderiza los resultados en tu navegador.
Recursos adicionales
Para aprender más sobre el uso de MongoDB, Nuxt y Vue, revisa los siguientes recursos:
Nuxt documentación
Vue documentation
Documentación del controlador Node.js

