Vue HTTP Request

Fetching data from APIs in Vue applications

🌐 What are HTTP Requests?

HTTP requests allow your Vue app to communicate with servers and APIs to fetch or send data. Use the native fetch API or libraries like Axios to make GET, POST, PUT, and DELETE requests easily.


<!-- Basic HTTP Request -->
<template>
  <div>
    <h2>User: {{ user.name }}</h2>
    <p>Email: {{ user.email }}</p>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const user = ref({})

onMounted(async () => {
  const response = await fetch('https://api.example.com/user/1')
  user.value = await response.json()
})
</script>
                                    

Key HTTP Concepts

📥

GET Request

Fetch data from server

const res = await fetch('/api/data')
const data = await res.json()
📤

POST Request

Send data to server

await fetch('/api/data', {
  method: 'POST',
  body: JSON.stringify(data)
})

Loading States

Handle async operations

const loading = ref(true)
// fetch data
loading.value = false

Error Handling

Catch and display errors

try {
  await fetch('/api')
} catch (error) {
  console.error(error)
}

🔹 Fetch API - GET Request

Retrieve data from an API using the native fetch:

<template>
  <div>
    <h2>Posts</h2>
    <p v-if="loading">Loading...</p>
    <p v-if="error">Error: {{ error }}</p>
    
    <ul v-if="posts.length">
      <li v-for="post in posts" :key="post.id">
        {{ post.title }}
      </li>
    </ul>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const posts = ref([])
const loading = ref(true)
const error = ref(null)

onMounted(async () => {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts')
    posts.value = await response.json()
  } catch (err) {
    error.value = err.message
  } finally {
    loading.value = false
  }
})
</script>

🔹 POST Request - Submit Data

Send data to a server using POST method:

<template>
  <form @submit.prevent="submitForm">
    <input v-model="formData.title" placeholder="Title" />
    <textarea v-model="formData.body" placeholder="Body"></textarea>
    <button type="submit" :disabled="submitting">
      {{ submitting ? 'Submitting...' : 'Submit' }}
    </button>
    <p v-if="success">Post created successfully!</p>
  </form>
</template>

<script setup>
import { ref } from 'vue'

const formData = ref({ title: '', body: '' })
const submitting = ref(false)
const success = ref(false)

async function submitForm() {
  submitting.value = true
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(formData.value)
    })
    const result = await response.json()
    success.value = true
    console.log('Created:', result)
  } catch (error) {
    console.error('Error:', error)
  } finally {
    submitting.value = false
  }
}
</script>

🔹 Using Axios Library

Axios provides a simpler API for HTTP requests:

<template>
  <div>
    <h2>Users</h2>
    <div v-for="user in users" :key="user.id">
      {{ user.name }}
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'

const users = ref([])

onMounted(async () => {
  try {
    const { data } = await axios.get('https://jsonplaceholder.typicode.com/users')
    users.value = data
  } catch (error) {
    console.error('Error fetching users:', error)
  }
})

// POST with Axios
async function createUser(userData) {
  const { data } = await axios.post('/api/users', userData)
  return data
}
</script>

🔹 Composable for Reusable Fetch

Create a reusable composable for HTTP requests:

// composables/useFetch.js
import { ref } from 'vue'

export function useFetch(url) {
  const data = ref(null)
  const error = ref(null)
  const loading = ref(true)

  async function fetchData() {
    loading.value = true
    try {
      const response = await fetch(url)
      data.value = await response.json()
    } catch (err) {
      error.value = err
    } finally {
      loading.value = false
    }
  }

  fetchData()
  return { data, error, loading }
}

// Usage in component
import { useFetch } from './composables/useFetch'
const { data, error, loading } = useFetch('https://api.example.com/data')

🧠 Test Your Knowledge

Which HTTP method is used to retrieve data from a server?