๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ‘“Vue

[Vue]Want Reuse? Use Composables, ์žฌ์‚ฌ์šฉ์—๋Š” ๋ฏน์Šค์ธ ๋Œ€์‹  ์ปดํฌ์ €๋ธ”

by ๋นˆ์„ฑ_ 2022. 5. 12.
๋ฐ˜์‘ํ˜•

Intro

๊ธฐ์กด, ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ Vue2์—์„œ๋Š” ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ Mixin(๋ฏน์Šค์ธ)์„ ํ™œ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. Vue3๋กœ ๋„˜์–ด์˜ค๋ฉด์„œ Mixin์„ ๋Œ€์ฒดํ•˜๋Š” Composables์ด ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. Vue3 ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋Š” Mixin ๋Œ€์‹  Composables๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋ฅผ ์ถ”์ฒœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ƒ๊ฐ๋ณด๋‹ค Composables๋ฅผ ์†Œ๊ฐœํ•ด์ฃผ๋Š” ๋ฌธ์„œ(ํ˜น์€ ๊ธ€)๊ฐ€ ํ•œ๊ตญ์–ด๋กœ ๋œ ๊ฑด ์—†๋”๊ตฐ์š”. ์•„์ง Vue3๋Š” ํ•œ๊ตญ์—์„œ ์‚ฌ์šฉํ•˜์‹œ๋Š” ๋ถ„๋“ค์ด ์กฐ๊ธˆ ์ ์€ ๊ฒŒ ์•„๋‹Œ๊ฐ€ ์‹ถ๋„ค์š”.

์–ด์จŒ๋“  ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์š”์•ฝํ•˜๋Š” ๊ธ€์ด๊ฒ ์ง€๋งŒ Composables์— ๋Œ€ํ•ด์„œ ์ฃผ์ €๋ฆฌ์ฃผ์ €๋ฆฌ ๋– ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค

Result

// App.vue

<script setup>
import {useMouse} from '@/composables/mouse';
...

const { x, y } = useMouse();

...
</script>

<template>
  <div>
    Mouse position is at: {{ x }}, {{ y }}
  </div>
    ...
</template>

 

// mouse.js

import {onMounted, onUnmounted, ref} from 'vue';
...

export function useMouse() {
  const x = ref(0)
  const y = ref(0)

  function update(event) {
    x.value = event.pageX
    y.value = event.pageY
  }

    ...

  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.addEventListener('mousemove', update))

  return { x, y }
}

 

๋‘ ๊ฐœ์˜ ์Šคํฌ๋ฆฝํŠธ ์ค‘ ์•„๋ž˜์ชฝ์ธ mouse.js๊ฐ€ Composables์˜ ๊ตฌํ˜„์ฒด์ž…๋‹ˆ๋‹ค.

Composables๋Š” function์„ export ํ•˜๋Š” ๊ฒƒ์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.(export default๋ฅผ ์‚ฌ์šฉํ•˜์…”๋„ ์ƒ๊ด€์—†์Šต๋‹ˆ๋‹ค.) ES6์— ์ต์ˆ™ํ•˜์‹  ๋ถ„๋“ค์ด๋ผ๋ฉด ํŠน๋ณ„ํ•  ๊ฒƒ ์—†๋Š” ๋ชจ์Šต์ด์ฃ .

composables function(mouse.js)์€ ref๋กœ ์ƒ์„ฑ๋œ ๋ณ€์ˆ˜, x์™€ y๋ฅผ return ํ•ด์ค๋‹ˆ๋‹ค. App.vue์—์„œ๋Š” composable function์„ ์‹คํ–‰ํ•ด x์™€ y๋ฅผ return ๋ฐ›์•„ ์›ํ•˜๋Š” ์šฉ๋„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ref์˜ ๋ฐ˜์‘์„ฑ์€ ์‚ฌ๋ผ์ง€์ง€ ์•Š๊ณ  ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

 

์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ๋Š” ์ด๊ณณ์—์„œ ํ™•์ธ ๊ฐ€๋Šฅํ•˜์‹ญ๋‹ˆ๋‹ค.

์ฃผ์ €๋ฆฌ์ฃผ์ €๋ฆฌ

Result์—์„œ ๋ณด์—ฌ๋“œ๋ฆฐ ์˜ˆ์ œ๋Š” Composables๋ฅผ ์†Œ๊ฐœํ•ด์ฃผ๋Š” Vue3์˜ ๊ณต์‹ ๋ฌธ์„œ ๊ฐ€์žฅ ์ƒ๋‹จ์— ์žˆ๋Š” ๊ธฐ๋ณธ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์˜ˆ์ œ ํ•˜๋‚˜๋งŒ ๋” ์ฃผ์ €๋ฆฌ์ฃผ์ €๋ฆฌ ๋– ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

composables function์€ ๋‹ค๋ฅธ composables function๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// mouse.js

import {useEventListener} from '@/composables/event';

export function useMouse() {
  const x = ref(0)
  const y = ref(0)

  function update(event) {
    x.value = event.pageX
    y.value = event.pageY
  }

  useEventListener(window, 'mousemove', update)

  // onMounted(() => window.addEventListener('mousemove', update))
  // onUnmounted(() => window.addEventListener('mousemove', update))

  return { x, y }
}

 

// event.js

import {onMounted, onUnmounted} from 'vue';

export function useEventListener(target, event, callback) {
  onMounted(() => target.addEventListener(event, callback))
  onUnmounted(() => target.addEventListener(event, callback))
}

 

๊ธฐ์กด mouse composables function์—์„œ window ๊ฐ์ฒด์— ์ด๋ฒคํŠธ๋ฅผ ์—ฐ๊ฒฐํ–ˆ๋˜ ๋ถ€๋ถ„์„ event.js๋ผ๋Š” ์ƒˆ๋กœ์šด composables function์„ ์ด์šฉํ•ด์„œ ํ’€์–ด๋‚ธ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค.

์ œ๊ฐ€ ์†Œ๊ฐœํ•ด๋“œ๋ฆฐ ์˜ˆ์ œ ์ด์™ธ์—๋„ ๊ณต์‹ ๋ฌธ์„œ์—์„œ๋Š” ๋น„๋™๊ธฐ ์ƒํƒœ์— ๋Œ€ํ•œ ์˜ˆ์ œ(fetch๋ฅผ composables function์œผ๋กœ ๋งŒ๋“  ์˜ˆ์ œ)์™€ composables function์—์„œ unref์™€ reactive๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ถ๊ธˆํ•˜์‹  ๋ถ„์€ ์•„๋ž˜ ๋งํฌ๋กœ ๋“ค์–ด๊ฐ€์„œ ํ™•์ธํ•˜์‹œ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

https://vuejs.org/guide/reusability/composables.html

 

Composables | Vue.js

 

vuejs.org

๊ธ€ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€