Projeto frontend Vue.js para consumir API REST da NASA para visualização da imagem destaque do dia, utilizando tecnologias Vue 3 Composition API com Vue Router, TypeScript com Volar, Vite, Axios, ESLint e Pinia.
VITE_NASA_API_KEY=SUA_CHAVE_DE_API_NASA
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
});
import axios from "axios";
export const api = axios.create({
baseURL: "https://api.nasa.gov",
});
import { api } from "./api";
const API_KEY = import.meta.env.VITE_NASA_API_KEY;
export const getApod = async () => {
const response = await api.get("/planetary/apod", {
params: { api_key: API_KEY },
});
return response.data;
};
export interface Apod {
title: string;
explanation: string;
url: string;
date: string;
}
import { ref, onMounted } from "vue";
import { getApod } from "@/services/nasaService";
import type { Apod } from "@/types/Apod";
export function useApod() {
const data = ref<Apod | null>(null);
const loading = ref(true);
const error = ref<string | null>(null);
const fetchApod = async () => {
try {
data.value = await getApod();
} catch (err) {
error.value = "Erro ao carregar dados";
} finally {
loading.value = false;
}
};
onMounted(fetchApod);
return { data, loading, error };
}
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "@/views/HomeView.vue";
const routes = [
{ path: "/", component: HomeView },
];
export const router = createRouter({
history: createWebHistory(),
routes,
});
import { createPinia } from "pinia";
export const pinia = createPinia();
import { createApp } from "vue";
import App from "./App.vue";
import { router } from "./router";
import { pinia } from "./store";
const app = createApp(App);
app.use(router);
app.use(pinia);
app.mount("#app");
<script setup lang="ts">
import { useApod } from "@/composables/useApod";
const { data, loading, error } = useApod();
</script>
<template>
<div>
<h1>NASA (Foto do Dia):</h1>
<div v-if="loading">Carregando</div>
<div v-else-if="error">{{ error }}</div>
<div v-else-if="data">
<h2>{{ data.title }}</h2>
<img :src="data.url" width="500">
<p>{{ data.explanation }}</p>
</div>
<h3>JSON recebido:</h3>
<pre v-if="data">
{{ JSON.stringify(data, null, 2) }}
</pre>
</div>
</template>
<template>
<router-view />
</template>
Elaborado por Mateus Schwede
ubsocial.github.io