FrameWorks/Vue

VueRouter의 Data Fetching 파헤치기

ABCD 2024. 6. 27.

데이터 가져오기

때때로 경로가 활성화될 때 서버에서 데이터를 가져와야하는 경우가 발생 할 수 있습니다.
탐색 후 데이터를 가져오거나, 탐색 전 데이터를 가져오거나 할 수 있습니다.

탐색 후 데이터 가져오기

이 접근 방식은 즉시 들어오는 컴포넌트를 탐색하고 렌더링하며, 컴포넌트 자체에서 데이터를 가져오게 됩니다.
이는 네트워크를 통해 데이터를 가져오는 동안 로딩 상태를 표시할 수 있으며, 각 뷰에 대해 로딩을 다르게 처리할 수 있습니다.

<template>
    <div class="post">
        <div v-if="loading" class="loading">로딩 중...</div>

        <div v-if="error" class="error">{{ error }}</div>

        <div v-if="post" class="content">
            <h2>{{ post.title }}</h2>
            <p>{{ post.body }}</p>
        </div>
    </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { getPost } from './api.js'

const route = useRoute()

const loading = ref(false)
const post = ref(null)
const error = ref(null)

// 라우트의 params를 감시하여 데이터를 다시 가져옴
watch(() => route.params.id, fetchData, { immediate: true })

async function fetchData(id) {
    error.value = post.value = null
    loading.value = true

    try {
        // `getPost`을 여러분의 데이터 가져오기 유틸 / API 래퍼로 대체
        post.value = await getPost(id)  
    } catch (err) {
        error.value = err.toString()
    } finally {
        loading.value = false
    }
}
</script>

탐색 전 데이터 가져오기

beforeRouteEnter를 통해 컴포넌트가 렌더링되기 전에 데이터를 가져옵니다.
데이터를 정상적으로 가져왔다면, next 호출 후 콜백함수를 이용해 데이터를 가져옵니다.

export default {
    data() {
        return {
            post: null,
            error: null,
        }
    },
    async beforeRouteEnter(to, from, next) {
        try {
            const post = await getPost(to.params.id)
            // 아래 정의된 `setPost` 메서드
            next(vm => vm.setPost(post))
        } catch (err) {
            // 아래 정의된 `setError` 메서드
            next(vm => vm.setError(err))
        }
    },
    // 라우트 변경이 일어나고 이 컴포넌트가 이미 렌더링 되었다면,
    // 로직이 약간 달라질 것입니다.
    beforeRouteUpdate(to, from) {
        this.post = null
        getPost(to.params.id).then(this.setPost).catch(this.setError)
    },
    methods: {
        setPost(post) {
            this.post = post
        },
        setError(err) {
            this.error = err.toString()
        }
    }
}
728x90
반응형

댓글

💲 추천 글