Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Integra MongoDB con Nuxt y Vue

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

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.

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.

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.

1

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.

2

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.

3

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

La interfaz CLI te solicita configurar tu proyecto. Utiliza las siguientes respuestas:

  1. Mensaje del sistema: Necesita instalar los siguientes paquetes: create-nuxt@latest-number. ¿La instalación puede 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. Pregunta: ¿Dónde te gustaría crear tu proyecto?

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

  4. Mensaje: ¿Qué gestor de paquetes te gustaría usar?

    Respuesta: npmSeleccione.

  5. Solicitud: ¿Inicializar el repositorio git?

    Respuesta: Seleccione Yes o No en función de sus preferencias.

  6. Sugerencia: ¿Le gustaría instalar alguno de los módulos oficiales?

    Respuesta: NoSeleccione.

4

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.

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

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.

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 desde el archivo .env y configura el soporte de Tailwind para el estilo de tus componentes Vue.

3

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:

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

4

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:

server/api/restaurants/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 hace query a la colección restaurants. Recupera los primeros 50 documentos de restaurantes 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

Abre el archivo server/api/restaurants/browse.get.ts y añade el siguiente código:

server/api/restaurants/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 Queens para restaurantes cuyos nombres contengan la palabra Moon y devuelve los documentos coincidentes como una respuesta JSON.

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.

1

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:

aplicación/assets/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

Abre el archivo app/components/RestaurantList.vue y añade el siguiente código:

app/components/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 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.

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

Abre el archivo app/components/Navbar.vue y añade el siguiente código:

app/components/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 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.

4

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:

app/pages/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 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:

app/pages/browse.vue
<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.

6

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

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

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

Realiza los siguientes pasos para iniciar el servidor y ver los datos de restaurante renderizados.

1

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
2

Abre http://localhost:3000/ en tu navegador. La página de aterrizaje inicial muestra los primeros 50 restaurantes en la base de datos de sample_restaurants.

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

Haz clic en el enlace Filtered Restaurants en la barra de navegación para ver los resultados de filtro 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 cuyos nombres contienen la palabra "Moon".

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

Para aprender más sobre el uso de MongoDB, Nuxt y Vue, revisa los siguientes recursos:

Volver

Integración de Meteor y Vue

En esta página