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 Nuxt manejan la lógica de la API y las interacciones de 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 proporcionar un framework completo con un entorno de ejecución de Node.js para rutas de servidor, lo que lo convierte en la solución ideal para el controlador Node.js de MongoDB. Puede conectarse a MongoDB directamente desde sus rutas de servidor Nuxt o utilidades del lado del servidor y devolver documentos a sus componentes de Vue sin necesidad de mantener un servicio backend o una capa de API independientes.
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 Comiencea utilizar la guía del controlador 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.
Verificar los prerrequisitos
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
Guarda tu cadena de conexión de MongoDB Atlas en una ubicación segura. La añadirás a tu archivo .env más adelante.
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:
yEscriba y presione Enter.Indicación: ¿Qué plantilla le gustaría utilizar?
Respuesta:
minimal - Minimal setup for Nuxt 4 (recommended)Seleccione.Pregunta: ¿Dónde te gustaría crear tu proyecto?
Respuesta: Presione
Enterpara aceptar el directorio predeterminado o escriba una ruta diferente.Mensaje: ¿Qué gestor de paquetes te gustaría usar?
Respuesta:
npmSeleccione.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:
NoSeleccione.
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, siga los pasos de esta sección para configurar el back-end.
Configurar su variable de entorno
Cree un archivo .env en la raíz de su proyecto para almacenar de forma segura su URI de conexión ejecutando el siguiente comando en la raíz de su 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
Abra el archivo nuxt.config.ts en la raíz de su proyecto y reemplace su contenido con el siguiente código para cargar variables de entorno y configurar el módulo CSS Tailwind:
// 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 ruta de restaurante 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.
Configurar 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 las directivas CSS de Tailwind que generan clases de utilidad para estilizar tu aplicación. Tailwind proporciona un conjunto completo de clases prediseñadas para diseño, espaciado, colores y tipografía sin necesidad de CSS personalizado.
Crear componente de lista de restaurantes
Ejecute los siguientes comandos en la raíz de su proyecto para crear un componente Vue para mostrar datos del 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!
Después de completar estos pasos, tendrá una aplicación Nuxt y Vue que se conecta a su implementación de MongoDB, ejecuta consultas en datos de restaurantes de muestra y presenta los resultados en su 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 delcontrolador Node.js

