# ์ปดํฌ์ง€์…˜ API Vue 2Vue 3

์ปดํฌ์ง€์…˜(Composition API)์€ ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์—ฌ์ฃผ๋Š” API์ž…๋‹ˆ๋‹ค. Vue 2์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ ํ˜•ํƒœ๋กœ ์ง€์› (opens new window)๋˜๋‹ค๊ฐ€ Vue 3๋ถ€ํ„ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ณต์‹ API๋กœ ์ฑ„ํƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์•„๋ž˜ ๊ฐœ๋…์€ Vue 2์™€ Vue 3์—์„œ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜ƒ

TIP

์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ด๋ž€ ๋ทฐ ํ”Œ๋Ÿฌ๊ทธ์ธ (opens new window)์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

# ์ปดํฌ์ง€์…˜ API ๊ธฐ์ดˆ

์ปดํฌ์ง€์…˜์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ ์•„๋ž˜ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋ฅผ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">change</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hi'
    }
  },
  methods: {
    changeMessage() {
      this.message = 'Hello'
    }
  }
}
</script>

์œ„ ์ฝ”๋“œ๋Š” message ๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์„ ์–ธํ•˜๊ณ  changeMessage ๋ผ๋Š” ๋ฉ”์„œ๋“œ๋กœ ๋ฉ”์‹œ์ง€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋ฅผ ์ปดํฌ์ง€์…˜์œผ๋กœ ๋ฐ”๊ฟ”๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">change</button>
  </div>
</template>

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

export default {
  setup() {
    const message = ref('Hello');
    const changeMessage = () => {
      message.value = 'Hi';
    }

    return { message, changeMessage }
  }
}
</script>

์ด ์ฝ”๋“œ๋Š” ๋ทฐ ์ธ์Šคํ„ด์Šค ์˜ต์…˜ ์†์„ฑ์œผ๋กœ setup ์ด๋ผ๋Š” ์†์„ฑ์„ ์„ ์–ธํ•˜๊ณ  ๊ทธ ์•ˆ์— message์™€ changeMessage๋ผ๋Š” ๋ฐ์ดํ„ฐ์™€ ๋ฉ”์„œ๋“œ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ปดํฌ์ง€์…˜์€ ์ด์ฒ˜๋Ÿผ setup ์ด๋ผ๋Š” API ์•ˆ์— ๋ฐ˜์‘์„ฑ(Vue Reactivity)์„ ์ฃผ์ž…ํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์„ ์–ธํ•˜๊ณ  ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์ œ์–ดํ•˜๋Š” ํ˜•ํƒœ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ๋Š” ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ ํ•˜๋‚˜์”ฉ ๊ตฌ์ฒด์ ์œผ๋กœ ์‚ดํŽด๋ณผ๊นŒ์š”?

# setup

setup์€ ์ปดํฌ์ง€์…˜ ์Šคํƒ€์ผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด ๊ผญ ์„ ์–ธํ•ด ์ฃผ์–ด์•ผ ํ•˜๋Š” ์˜ต์…˜์ž…๋‹ˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ ์˜ต์…˜ ์†์„ฑ์ด๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์‹ฑ๊ธ€ ํŒŒ์ผ ์ปดํฌ๋„ŒํŠธ๋‚˜ ๋ทฐ ์ธ์Šคํ„ด์Šค ์•ˆ์— ๋ฐ”๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ๋ทฐ ์ธ์Šคํ„ด์Šค
Vue.createApp({
  setup() {
    // ...
  }
});
<!-- ์‹ฑ๊ธ€ํŒŒ์ผ ์ปดํฌ๋„ŒํŠธ -->
<script>
export default {
  setup() {
    // ...
  }
}
</script>

# ref ์†Œ๊ฐœ

ref๋Š” ๋ทฐ์˜ ๋ฐ˜์‘์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” API์ž…๋‹ˆ๋‹ค. ๊ธฐ์กด์— data ์†์„ฑ์— ์„ ์–ธํ–ˆ๋˜ ๊ฐ’๋“ค์€ ๋ชจ๋‘ ๋ทฐ ์ธ์Šคํ„ด์Šค ๋ผ์ดํ”„์‚ฌ์ดํด ๊ณผ์ •์—์„œ ๋ฐ˜์‘์„ฑ์ด ์ฃผ์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐ˜์‘์„ฑ ์ฃผ์ž…์„ ์ข€ ๋” ๋ช…์‹œ์ ์ธ API๋กœ ๋ฐ”๊พผ ๊ฒƒ์ด์ฃ .

์•„๋ž˜ ๋‘ ์ฝ”๋“œ๋Š” ๊ฐ™์€ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

// ๋ทฐ ์ธ์Šคํ„ด์Šค ์˜ต์…˜ ์Šคํƒ€์ผ
Vue.createApp({
  data() {
    return {
      message: ''
    }
  }
});
// ๋ทฐ ์ปดํฌ์ง€์…˜ ์Šคํƒ€์ผ
import { ref } from 'vue';

createApp({
  setup() {
    const message = ref('');

    return { message }
  }
});

๋ทฐ ์ธ์Šคํ„ด์Šค ์˜ต์…˜ ์†์„ฑ์œผ๋กœ ์ œ๊ณต๋˜๋Š” data๋ฅผ ์“ธ๊ฑฐ๋ƒ ๊ทธ๋ ‡์ง€ ์•Š๊ณ  ๋ณ„๋„์˜ ref ๋ผ๋Š” API๋ฅผ ์ž„ํฌํŠธํ•ด์„œ setup ์•ˆ์—์„œ ์‚ฌ์šฉํ• ๊ฑฐ๋ƒ์˜ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

# ref ์ฒซ ๋ฒˆ์งธ ํŠน์ง• - setup ํ•จ์ˆ˜์—์„œ ๊ผญ ๋ฐ˜ํ™˜ํ•˜๊ธฐ

setup ์•ˆ์—์„œ ref๋กœ ์„ ์–ธ๋œ ๊ฐ’์€ ํ•ญ์ƒ ๋ฐ˜ํ™˜ํ•ด ์ค˜์•ผ ํ…œํ”Œ๋ฆฟ ํ‘œํ˜„์‹ ๋˜๋Š” ๊ฐ™์€ ์ธ์Šคํ„ด์Šค(์ปดํฌ๋„ŒํŠธ) ๋‚ด์˜ ๋‹ค๋ฅธ ๋กœ์ง์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.







ย 



ย 




import { ref } from 'vue';

createApp({
  setup() {
    const message = ref('');

    return { message }
  },
  methods: {
    changeMessage() {
      this.message = 'Hello Compositon';
    }
  }
});

๋งŒ์•ฝ ์•„๋ž˜์™€ ๊ฐ™์ด setup ํ•จ์ˆ˜์—์„œ ref๋กœ ์„ ์–ธ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ์—์„œ ์ธ์‹ํ•˜์ง€ ๋ชปํ•ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒ๋‹ˆ๋‹ค.









ย 




import { ref } from 'vue';

createApp({
  setup() {
    const message = ref('');
  },
  methods: {
    changeMessage() {
      this.message = 'Hello Compositon'; // `message`๊ฐ€ ์„ ์–ธ๋˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ
    }
  }
});

# ref ๋‘ ๋ฒˆ์งธ ํŠน์ง• - .value

ref๋กœ ์„ ์–ธ๋œ ๊ฐ’์„ setup ํ•จ์ˆ˜ ์•ˆ์—์„œ ๋‹ค๋ฃฐ ๋•Œ๋Š” .value๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ ์ฝ”๋“œ๋ฅผ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

<script>
export default {
  setup() {
    // data
    const message = ref('hi');
    
    // methods
    const changeMessage = () => {
      message.value = 'Hello';
    };

    return { message, changeMessage }
  }
}
</script>

์œ„ ์ฝ”๋“œ๋Š” message ๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์„ ์–ธํ•˜๊ณ  changeMessage๋ผ๋Š” ๋ฉ”์„œ๋“œ ํ•จ์ˆ˜๋กœ message ๋ฐ์ดํ„ฐ์˜ ๊ฐ’์„ Hello๋กœ ๋ฐ”๊พธ๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ changeMessage ํ•จ์ˆ˜๋ฅผ ๋ณด๋ฉด message ๊ฐ’์„ ๋ฐ”๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ .value ๋ผ๋Š” ๊ฐ’์— ์ ‘๊ทผํ•˜์—ฌ ๋ณ€๊ฒฝํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ด์ฒ˜๋Ÿผ setup ํ•จ์ˆ˜ ๋‚ด์—์„œ ref๋กœ ์„ ์–ธ๋œ ๊ฐ’์„ ์ฝ๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ๋•Œ๋Š” .value ๊ฐ’์„ ๋‹ค๋ค„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์œ„ ์ฝ”๋“œ์˜ setup ํ•จ์ˆ˜์—์„œ ๋ฐ˜ํ™˜๋œ message๋Š” ํ…œํ”Œ๋ฆฟ ํ‘œํ˜„์‹์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<template>
  <p>{{ message }}</p>
</template>

์™œ setup ํ•จ์ˆ˜ ์•ˆ์—์„œ๋Š” .value๋กœ ๋ฉ”์‹œ์ง€ ๊ฐ’์„ ์ ‘๊ทผํ–ˆ๋Š”๋ฐ ํ…œํ”Œ๋ฆฟ ํ‘œํ˜„์‹์—์„œ๋Š” message ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ–ˆ์„๊นŒ์š”? ๊ทธ ์ด์œ ๋Š” ๋ฐ”๋กœ ๋ทฐ ๋‚ด๋ถ€์ ์œผ๋กœ message ์•ˆ์— ์žˆ๋Š” value ๊ฐ’์„ ๊บผ๋‚ด์–ด ํ…œํ”Œ๋ฆฟ ํ‘œํ˜„์‹์— ์—ฐ๊ฒฐํ•ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋™์ž‘์€ ๊ธฐ์กด์˜ Vue 2์—์„œ ๊ฐœ๋ฐœํ•˜๋˜ ๊ฒฝํ—˜์„ ํฌ๊ฒŒ ํ•ด์น˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ๊ณ ์•ˆ๋œ ์žฅ์น˜๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# ์ฐธ๊ณ  ์ž๋ฃŒ

์ปดํฌ์ง€์…˜์— ๋Œ€ํ•ด ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.