Docs Menu
Docs Home
/ /

Integrar MongoDB con Nuxt y Vue

Este tutorial te guía en la creación de una aplicación Nuxt que utiliza Vue y se integra con MongoDB. Nuxt es un framework de Vue que proporciona enrutamiento basado en archivos, renderizado del lado del servidor y rutas API integradas a través de su motor de servidor Nitro. Nuxt, combinado con Vue, te permite crear aplicaciones completas sin un servidor back-end independiente.

La aplicación de 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

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 asigna fácilmente a objetos JavaScript. Como resultado, puede trabajar sin problemas con datos de MongoDB en sus componentes de Vue, ya sea usando la API Options o la API Composition. Los documentos que obtiene de MongoDB se pueden pasar directamente a sus componentes y plantillas, lo que reduce la necesidad de complejas transformaciones de datos o una capa adicional de mapeo objeto-relacional (ORM).

Las utilidades de renderizado del lado del servidor (SSR) y obtención de datos de Nuxt permiten consultar MongoDB en el servidor antes de renderizar las páginas. Esto permite nutrir los componentes de Vue con datos listos para usar, mejorando el rendimiento percibido y el SEO de las aplicaciones basadas en datos.

Este tutorial le muestra cómo crear una aplicación web con Nuxt y Vue. La aplicación accede a datos de muestra de restaurantes, los consulta y muestra los resultados en un sitio web alojado localmente. El tutorial también incluye instrucciones para conectarse a un clúster de MongoDB alojado en MongoDB Atlas y acceder y mostrar datos de su base de datos.

Tip

Si prefiere conectarse a MongoDB utilizando el controlador Node.js sin Nuxt, consulte la Comiencea utilizar la guía del controlador Node.js.

Siga los pasos de esta sección para instalar las dependencias del proyecto, crear un clúster Atlas y configurar los directorios de la aplicación.

1

Para crear la aplicación de inicio rápido, instale el siguiente software en su entorno de desarrollo:

Requisito previo

notas

Utilice la versión 20 o posterior.

Editor de código

Este tutorial utiliza Visual Studio Code, pero puedes usar el editor que prefieras.

Aplicación de terminal y shell

Para usuarios de macOS o Linux, usen Terminal o una aplicación similar. Para usuarios de Windows, usen PowerShell.

2

MongoDB Atlas es un servicio de base de datos en la nube totalmente administrado que aloja sus implementaciones de MongoDB. Si no tiene una implementación de MongoDB, puede crear un clúster de MongoDB gratis (sin tarjeta de crédito) completando el tutorial de introducción a MongoDB.

Tip

Asegúrese de que el sample_restaurants El conjunto de datos se carga en el clúster. Este tutorial consulta los datos de ese conjunto. Para saber cómo cargar el sample_restaurants conjunto de datos en el clúster, consulte el tutorial "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.

3

Usa la CLI oficial de Nuxt para inicializar un nuevo proyecto Nuxt con Vue. Abre tu terminal y navega al directorio del proyecto que desees.

Ejecuta el comando de inicialización:

npm create nuxt@latest

La CLI le solicita que configure su proyecto. Utilice las siguientes respuestas:

  1. Aviso: Se necesitan instalar los siguientes paquetes: create-nuxt@latest-number. ¿Desea continuar?

    Respuesta: y Escriba y presione Enter.

  2. Indicación: ¿Qué plantilla le gustaría utilizar?

    Respuesta: minimal - Minimal setup for Nuxt 4 (recommended)Seleccione.

  3. Indicación: ¿Dónde le gustaría crear su proyecto?

    Respuesta: Presione Enter para aceptar el directorio predeterminado o escriba una ruta diferente.

  4. Pregunta: ¿Qué gestor de paquetes le gustaría utilizar?

    Respuesta: npmSeleccione.

  5. Pregunta: ¿Inicializar repositorio git?

    Respuesta: Seleccione Yes o No según su preferencia.

  6. Aviso: ¿Quieres instalar alguno de los módulos oficiales?

    Respuesta: NoSeleccione.

4

Navegue al directorio de su proyecto e instale el controlador MongoDB, los íconos 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.

Después de configurar la estructura del proyecto, siga los pasos de esta sección para configurar el back-end.

1

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

Abra el archivo .env y agregue su URI de conexión:

MONGODB_URI=<Your Connection URI>

Nota

Reemplace <Your Connection URI> con la URI de conexión que recibió de MongoDB Atlas.

2

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:

nuxt.config.ts
// 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 del archivo .env y configura el soporte de Tailwind para diseñar sus componentes Vue.

3

Ejecute los siguientes comandos en la raíz de su proyecto para crear un archivo de utilidad que contenga la lógica de conexión de MongoDB:

mkdir -p server/utils
touch server/utils/mongodb.ts

Abra el archivo server/utils/mongodb.ts y agregue el siguiente código:

servidor/utils/mongodb.ts
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 MongoDB reutilizable que se conecta a su clúster Atlas mediante la URI de conexión almacenada en su 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.

4

Las rutas del servidor Nuxt gestionan las solicitudes de API e interactúan con la base de datos. Ejecute los siguientes comandos en la raíz del proyecto para crear una ruta de servidor que permita obtener datos del restaurante:

mkdir -p server/api/restaurants
touch server/api/restaurants/index.get.ts

Abra el archivo server/api/restaurants/index.get.ts y agregue el siguiente código:

servidor/api/restaurantes/index.get.ts
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 consulta la colección restaurants. Recupera los primeros 50 documentos del restaurante y los devuelve como una respuesta JSON.

5

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

Abra el archivo server/api/restaurants/browse.get.ts y agregue el siguiente código:

servidor/api/restaurantes/browse.get.ts
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 busca de restaurantes en Queens cuyos nombres contengan la palabra Moon y devuelve los documentos coincidentes como una respuesta JSON.

Después de configurar el back end, siga los pasos de esta sección para configurar la capa de presentación para su aplicación.

1

Ejecute el siguiente comando en la raíz de su proyecto para crear un archivo CSS principal para estilos globales:

mkdir -p app/assets/css
touch app/assets/css/main.css

Abra el archivo app/assets/css/main.css y agregue el siguiente código:

aplicación/activos/css/main.css
@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.

2

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

Abra el archivo app/components/RestaurantList.vue y agregue el siguiente código:

aplicación/componentes/RestaurantList.vue
<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 obtiene datos de restaurantes de la ruta de tu servidor Nuxt y los muestra en un diseño de cuadrícula adaptable. Adapta dinámicamente el punto final de la API y el contenido de la página según la ruta actual, mostrando todos los restaurantes o resultados filtrados.

3

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

Abra el archivo app/components/Navbar.vue y agregue el siguiente código:

aplicación/componentes/Navbar.vue
<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 muestra la barra de navegación sobre los resultados del restaurante y contiene el All Restaurants y Filtered Restaurants enlaces. Estos le permiten navegar entre las rutas.

4

Ejecute el siguiente comando en la raíz de su proyecto para crear una página de índice para la aplicación:

mkdir -p app/pages
touch app/pages/index.vue

Abra el archivo app/pages/index.vue y agregue el siguiente código:

aplicación/páginas/index.vue
<template>
<RestaurantList />
</template>

Este archivo muestra los resultados de la ruta del servidor index.get.ts utilizando los componentes RestaurantList y Navbar.

5

Ejecute el siguiente comando en la raíz de su proyecto para crear una nueva página Vue para mostrar datos filtrados del restaurante:

touch app/pages/browse.vue

Abra el archivo app/pages/browse.vue y agregue el siguiente código:

aplicación/páginas/browse.vue
<template>
<RestaurantList />
</template>

Este archivo muestra los resultados de una consulta filtrada en la base de datos sample_restaurants que devuelve todos los restaurantes en Queens cuyos nombres contienen la palabra Moon. También utiliza los componentes RestaurantList y Navbar para construir la página.

6

Abra el archivo app/App.vue y reemplace su contenido con el siguiente código para conectar los componentes:

aplicación/app.vue
<template>
<div class="w-full p-6 min-h-screen bg-gray-50">
<Navbar />
<NuxtPage />
</div>
</template>
7

Antes de continuar, asegúrese de que su árbol de archivos coincida con la estructura a continuación. Puede ignorar 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

Realice los siguientes pasos para iniciar el servidor y ver los datos del restaurante procesados.

1

Ejecute el siguiente comando en la raíz de su proyecto para iniciar el servidor de desarrollo:

npm run dev

Si tiene éxito, 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
2

Abra http://localhost:3000/ en su navegador. La página de inicio muestra los primeros 50 restaurantes de la base de datos sample_restaurants.

La aplicación de destino que muestra los primeros 50 restaurantes en la base de datos sample_restaurants.
3

Haga clic en el enlace Filtered Restaurants en la barra de navegación para ver los resultados filtrados de restaurantes. La página muestra todos los restaurantes en Queens cuyos nombres contienen la palabra Moon.

La página de restaurantes filtrados que muestra todos los restaurantes en Queens con nombres que contienen la palabra Moon.

¡Felicitaciones 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.

Para obtener más información sobre el uso de MongoDB, Nuxt y Vue, consulte los siguientes recursos:

Volver

Integración de Meteor y Vue

En esta página