Skip to content

๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ โ€‹

๊ฒฝ๋กœ๊ฐ€ ํ™œ์„ฑํ™”๋  ๋•Œ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž ํ”„๋กœํ•„์„ ๋ Œ๋”๋งํ•˜๊ธฐ ์ „์— ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ์ž์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • ์ด๋™ ํ›„ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ: ๋จผ์ € ์ด๋™์„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๋“ค์–ด์˜ค๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด ํ›…์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋™์•ˆ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋™ ์ „ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ: ๊ฒฝ๋กœ ์ง„์ž… ๊ฐ€๋“œ์—์„œ ์ด๋™ ์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ๋ฐ์ดํ„ฐ๊ฐ€ ๋ชจ๋‘ ์ค€๋น„๋œ ํ›„์— ์ด๋™์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์ˆ ์ ์œผ๋กœ ๋‘ ๋ฐฉ๋ฒ• ๋ชจ๋‘ ์œ ํšจํ•œ ์„ ํƒ์ด๋ฉฐ, ๊ถ๊ทน์ ์œผ๋กœ๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ๋‹ฌ๋ ค ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋™ ํ›„ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ โ€‹

์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š”, ์ฆ‰์‹œ ์ด๋™ํ•˜์—ฌ ๋“ค์–ด์˜ค๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ , ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋™์•ˆ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๊ณ , ๊ฐ ๋ทฐ๋งˆ๋‹ค ๋กœ๋”ฉ์„ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

route.params.id๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒŒ์‹œ๊ธ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋Š” Post ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค:

vue
<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>
vue
<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>
import { getPost } from './api.js'

export default {
  data() {
    return {
      loading: false,
      post: null,
      error: null,
    }
  },
  created() {
    // ๊ฒฝ๋กœ์˜ params๋ฅผ ๊ฐ์‹œํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค
    this.$watch(
      () => this.$route.params.id,
      this.fetchData,
      // ๋ทฐ๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ๋ฐ์ดํ„ฐ๊ฐ€
      // ์ด๋ฏธ ๊ด€์ฐฐ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค
      { immediate: true }
    )
  },
  methods: {
    async fetchData(id) {
      this.error = this.post = null
      this.loading = true

      try {
        // `getPost`๋ฅผ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ ํ‹ธ/ API ๋ž˜ํผ๋กœ ๊ต์ฒดํ•˜์„ธ์š”
        this.post = await getPost(id)
      } catch (err) {
        this.error = err.toString()
      } finally {
        this.loading = false
      }
    },
  },
}
</script>

์ด๋™ ์ „ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ โ€‹

์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ์‹ค์ œ๋กœ ์ƒˆ๋กœ์šด ๊ฒฝ๋กœ๋กœ ์ด๋™ํ•˜๊ธฐ ์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ๋“ค์–ด์˜ค๋Š” ์ปดํฌ๋„ŒํŠธ์˜ beforeRouteEnter ๊ฐ€๋“œ์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ , ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„์—๋งŒ next๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. next์— ์ „๋‹ฌ๋œ ์ฝœ๋ฐฑ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ๋œ ํ›„์— ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค:

js
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()
    }
  }
}

์‚ฌ์šฉ์ž๋Š” ๋“ค์–ด์˜ค๋Š” ๋ทฐ์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋™์•ˆ ์ด์ „ ๋ทฐ์— ๋จธ๋ฌด๋ฅด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋™์•ˆ ์ง„ํ–‰ ํ‘œ์‹œ์ค„์ด๋‚˜ ์–ด๋–ค ํ˜•ํƒœ์˜ ์ธ๋””์ผ€์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ์— ์‹คํŒจํ•œ ๊ฒฝ์šฐ, ์ „์—ญ ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€์™€ ๊ฐ™์€ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋‘๋ฅผ ์œ„ํ•œ ๋ฌธ์„œ ํ•œ๊ธ€ํ™”