๐Ÿ” ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค FE ๋ฐ๋ธŒ์ฝ”์Šค 5๊ธฐ TIL = v-model | keep-alive | ๋‹ค์ค‘ import | teleport | removeEventListener

Jun 2k (Jun2)ยท2023๋…„ 11์›” 27์ผ
0
post-thumbnail

2023.11.24 ๊ฐ•์˜

๐Ÿ’ป Intro & TMI

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์Šคํƒ€๋”” ๋ฐ ์ฃผ๋ง์—๋Š” ๊ฑด๊ฐ• ์ด์Šˆ ๋ฐ ๊ฐœ์ธ ์ผ์ •์œผ๋กœ TIL๋ฅผ ๋ฏธ์ฒ˜ ์ •๋ฆฌํ•˜์ง€ ๋ชปํ–ˆ๋‹ค.
๋ณธ๊ฒฉ์ ์œผ๋กœ Vue ํ”„๋กœ์ ํŠธ ์‹ค์Šต ๊ฐ•์˜ ์ „ ๋‚ด์šฉ๋“ค์ด๋ผ ๋‹ค์†Œ ์–ด๋ ค์šด ๋‚ด์šฉ๋“ค์ด ๋งŽ์•˜๋‹ค.
๊ทธ ์ค‘ ๊ผญ ๊ธฐ์–ตํ•ด๋‘๊ณ  ํ”„๋กœ์ ํŠธ ๋•Œ๋„ ์ž์ฃผ ์“ฐ์ผ ๊ฒƒ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด๋‚˜ ์ฃผ์˜์‚ฌํ•ญ๋“ค์„ ์š”์•ฝํ–ˆ๋‹ค.



๐Ÿง ์˜ค๋Š˜ ์ƒˆ๋กญ๊ฒŒ ๋ฐฐ์šด ๊ฒƒ

โœจ Vue ์ปดํฌ๋„ŒํŠธ ๊ฐ„ v-model ์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋„˜๊ฒจ์ค€ props๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ์œ„ํ•ด v-model ๋””๋ ‰ํ‹ฐ๋ธŒ๊ฐ€ ์กด์žฌํ•˜์ง€๋งŒ ์ด๊ฒƒ์„ props์—๋„ ๊ทธ๋ƒฅ ์Œฉ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด props ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅ ์›์น™ ๋•Œ๋ฌธ์— ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

๋”ฐ๋ผ์„œ ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ์ฝ”๋“œ ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค.

// App.vue ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ
<template>
  <h1>
    {{ msg }}
  </h1>
  <Hello
    v-model:message="msg"
    />
</template>

<script>
import Hello from '~/components/Hello'

export default {
  components: {
    Hello,
  },
  data() {
    return {
      msg: 'Hello Vue!',
    }
  }
}
</script>

๋จผ์ € ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์ธ App.vue์—์„œ๋Š” msg๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ props๋ฅผ ๋„˜๊ฒจ์ค˜์•ผ ํ•œ๋‹ค.
Hello ์ปดํฌ๋„ŒํŠธ์— props๋กœ ๋„˜๊ฒจ์ค„ ๋•Œ v-model๋กœ ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋˜๋Š”๋ฐ ์ด ๋•Œ ์˜†์— ๋„˜๊ฒจ์ค„ props์˜ ์ด๋ฆ„ message์„ :๊ณผ ํ•จ๊ป˜ ๊ฐ™์ด ์ถ”๊ฐ€ํ•˜์—ฌ ๋„˜๊ฒจ์ค€๋‹ค.
์ด๊ฒƒ์„ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  ๋„˜๊ฒจ์ฃผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” props ์†์„ฑ์—์„œ modelValue๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋„˜์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.

// Hello.vue
<template>
  <label>
    <input
      :value="message"
      @input="$emit('update:message', $event.target.value)" />
  </label>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      default: ''
    }
  }
}</script>

//...

์ด๋ ‡๊ฒŒ ๋„˜๊ฒจ๋ฐ›์€ props๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ Hello.vue์—์„œ message๋ผ๋Š” ์†์„ฑ์œผ๋กœ props ์†์„ฑ์œผ๋กœ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.
์ดํ›„ input ํƒœ๊ทธ์—์„œ ํ‘œ์‹œํ•  :value๋กœ ๋ฐ”์ธ๋”ฉํ•ด์ฃผ๊ณ  @input ์ด๋ฒคํŠธ์—๋Š” $emit์„ ์‚ฌ์šฉํ•ด์„œ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ์ง€์ •ํ•œ๋‹ค.
์ด ๋•Œ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ช…์œผ๋กœ update:message์ฒ˜๋Ÿผ ์–ด๋–ค props๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ธ์ง€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์— ๋„˜๊ฒจ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์ง์ ‘ props๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ˆ˜์ •ํ•  ์ˆ˜๋Š” ์—†์œผ๋‹ˆ ์ˆ˜์ •ํ•  ๋Œ€์ƒ์„ ์ด๋ฒคํŠธ๋ช…๊ณผ ํ•จ๊ป˜ ์•Œ๋ ค์ฃผ๊ณ  ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ทธ๊ฒƒ์„ ๋ฐ›์•„ ์ˆ˜์ •ํ•˜๋Š” ๊ฐœ๋…์ด๋‹ค. (์—„๋งˆ ์ด๊ฑฐ ํ•ด์ค˜~)

์ด๋ ‡๊ฒŒ ํ•ด์•ผ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ „์—ญ์ ์œผ๋กœ ์ƒํƒœ๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ณ  ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.



โœจ keep-alive๋ฅผ ํ†ตํ•œ ๋™์  ์ปดํฌ๋„ŒํŠธ

v-show ๋””๋ ‰ํ‹ฐ๋ธŒ์ฒ˜๋Ÿผ ์ „ํ™˜ ํšจ๊ณผ๊ฐ€ ๋งŽ์ด ์˜ˆ์ƒ๋˜๋Š” ๋™์  ์ปดํฌ๋„ŒํŠธ์— ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” keep-alive ํƒœ๊ทธ๊ฐ€ ์žˆ๋‹ค.

๊ธฐ๋ณธ์ ์ธ ๋™์  ์ปดํฌ๋„ŒํŠธsms :is ์†์„ฑ์„ ํ†ตํ•ด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ช…์ด ์ผ์น˜ํ•  ๊ฒฝ์šฐ Hello์™€ World ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

//...
<button @click="currentComponent = 'Hello'">
  Hello!
</button>
<button @click="currentComponent = 'World'">
  World!
</button>

<component :is="currentComponent" />
//...

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค created์™€ unmounted ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ์ฝ˜์†”๋กœ ํ™•์ธํ•ด๋ณด๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ์ƒ์„ฑํ•˜๊ณ  unmount๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์ด ๋ฐ˜๋ณต๋  ์ˆ˜ ์žˆ๊ธฐ์— ์ด๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด keep-alive ํƒœ๊ทธ์ด๋‹ค.

//..
<keep-alive>
  <component :is="currentComponent" />
</keep-alive>

์œ„์™€ ๊ฐ™์ด ๋™์  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ์‹ธ๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น ๋™์  ์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋ฏธ created ์ƒํƒœ์—์„œ ์ปดํฌ๋„ŒํŠธ๋ช…์— ๋งž๊ฒŒ ๋ณ€ํ™”ํ•œ๋‹ค.

๋ฌด์กฐ๊ฑด keep-alive ํƒœ๊ทธ๊ฐ€ ์ข‹์€ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.
์ „ํ™˜ ํšจ๊ณผ๊ฐ€ ๋งŽ์ด ํ•„์š”์—†๋Š”๋ฐ๋„ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์žก์•„๋จน๊ฒŒ ๋˜๋ฏ€๋กœ ํ•ญ์ƒ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.



โœจ ์—ฌ๋Ÿฌ Vue ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•œ๊บผ๋ฒˆ์— import

App.vue์—์„œ ๋‹ค์–‘ํ•œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด import ๊ตฌ๋ฌธ์ด ์—„์ฒญ ๋งŽ์•„์ง€๊ฒŒ ๋œ๋‹ค.

// App.vue
<script>
  import TextField from '~/components/fields/TextField'
  import SimpleRadio from '~/components/fields/SimpleRadio'
  // ๋” ๋งŽ์•„์งˆ ์ˆ˜๋„ ์žˆ๋‹ค...
  
  export default {
  	components: {
  		TextField,
  		SimpleRadio
  		// ๋” ์ถ”๊ฐ€ ๊ฐ€๋Šฅ...
  	},
  	// ...
  }
</script>

์ด๋Ÿด ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ํ•˜๋‚˜์˜ js ํŒŒ์ผ๋กœ ๋ฌถ์–ด์„œ import ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๋จผ์ € index.js๋ผ๋Š” ํŒŒ์ผ๋กœ export ๊ตฌ๋ฌธ์„ ๊ทธ๋ฃนํ™”ํ•œ๋‹ค.
์ด๋•Œ default as ๊ตฌ๋ฌธ์œผ๋กœ export ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ช…์„ ์ง€์ •ํ•œ๋‹ค.

// index.js
export { default as TextField } from './TextField'
export { default as SimpleRadio } from './SimpleRadio'

๋‹ค์Œ App.vue์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด importํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ํ•œ์ธต ๊น”๋”ํ•˜๊ฒŒ ํ•œ๊บผ๋ฒˆ์— import๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

// App.vue
<script>
  import * as FieldComponents from '~/components/fields/index.js'
  
  export default {
  	components: {
  		...FieldComponents
  	},
  	// ...
  }
</script>

ํ”„๋กœ์ ํŠธ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐฏ์ˆ˜๋ฅผ ๋น„๋ก€ํ•ด์„œ ๋งŽ์•„์ง€๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ ์œ„์™€ ๊ฐ™์ด import ํ•ด์ฃผ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•  ๊ฒƒ ๊ฐ™๋‹ค.



โœจ ์ปดํฌ๋„ŒํŠธ ํ…œํ”Œ๋ฆฟ ์œ„์น˜๋ฅผ ํ…”๋ ˆํฌํŠธ!! teleport

๊ธฐ๋ณธ์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์˜ ํ…œํ”Œ๋ฆฟ์„ ์ž‘์„ฑํ•œ ์œ„์น˜์— ๋งž๊ฒŒ ์žˆ๋Š” ๊ทธ๋Œ€๋กœ DOM์— ๋ Œ๋”๋ง๋œ๋‹ค.
ํ•˜์ง€๋งŒ CSS์— ๋Œ€ํ•œ ์ด์Šˆ๋กœ ์ธํ•ด ํŠน์ • ์ปดํฌ๋„ŒํŠธ์˜ ์œ„์น˜๋ฅผ ๋…ผ๋ฆฌ์ ์ธ ๊ตฌํ˜„ ์œ„์น˜๊ฐ€ ์•„๋‹Œ ๊ณณ์— ๋ฐฐ์น˜ํ•˜๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์žˆ๋‹ค.
๊ฐ•์˜์—์„œ๋Š” position: fixed๋ฅผ ๊ฐ€์ง„ ํ•˜์œ„ div์š”์†Œ๊ฐ€ bodyํƒœ๊ทธ๊ฐ€ ์•„๋‹Œ transform ์†์„ฑ์„ ๊ฐ€์ง„ ๋ถ€๋ชจ ํƒœ๊ทธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ณ ์ •๋˜๋Š” ๊ฒƒ์„ ์˜ˆ์‹œ๋กœ ๋“ค์—ˆ๋‹ค.

์ด์™€ ๊ฐ™์ด ๋‚ด๊ฐ€ ์›ํ•˜๋Š” body ํƒœ๊ทธ์— ํŠน์ • ์ปดํฌ๋„ŒํŠธ๋ฅผ ์œ„์น˜(์ด๋™)์‹œํ‚ค๊ณ  ์‹ถ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ?
๋ฐ”๋กœ teleport ํƒœ๊ทธ์ด๋‹ค.

// Modal.vue
<teleport to="body">
    <template v-if="modelValue">
      <div
        class="modal"
        @click="offModal">
        <div>
        <!-- ... -->
        </div>
      </div>
	</template>
</teleport>

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด๋™์‹œํ‚ค๊ณ  ์‹ถ์€ ์š”์†Œ๋“ค์„ templateํƒœ๊ทธ๋กœ ๋ฌถ์€ ๋’ค ํ•ด๋‹น templateํƒœ๊ทธ๋ฅผ ๋‹ค์‹œ teleport ํƒœ๊ทธ๋กœ ๊ฐ์‹ผ๋‹ค.
๊ทธ๋ฆฌ๊ณ  to="css์„ ํƒ์ž" ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์„œ CSS ์„ ํƒ์ž๋กœ ํ•ด๋‹น ์š”์†Œ๋“ค์ด ๋‚ด๋ถ€์— ๋“ค์–ด๊ฐˆ ๋ถ€๋ชจ DOM ์š”์†Œ๋ฅผ ์ง€์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

teleport ํƒœ๊ทธ ์•ˆ์— ์žˆ๋Š” v-bind ๋ฐ์ดํ„ฐ๋‚˜ @ ํด๋ฆญ ์ด๋ฒคํŠธ ๋“ฑ์„ ๋ชจ๋‘ ์œ ์ง€๋˜๊ธฐ ๋•Œ๋ฌธ์— DOM ๊ธฐ์ค€์œผ๋กœ ์œ„์น˜๋งŒ ์ด๋™์‹œํ‚ค๊ณ  ์‹ถ์„ ๋–„ ์•„์ฃผ ์œ ์šฉํ•˜๋‹ค.
์˜ˆ์‹œ๋กœ ๋“  ๋ชจ๋‹ฌ๊ณผ ๊ฐ™์ด ๋ ˆ์ด์•„์›ƒ ์ธก๋ฉด์—์„œ ํŠน์ˆ˜ํ•˜๊ฒŒ ์œ„์น˜ํ•ด์•ผ ํ•˜๋Š” ์š”์†Œ๋“ค์— ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.



โœจ removeEventListener์˜ ํ•„์š”์„ฑ

๋ณดํ†ต์€ ์ด๋ฒคํŠธ๋ฅผ ์ง€์ •ํ•  ๋•Œ addEventListener๋กœ ์ด๋ฒคํŠธ๋ฅผ ๋ถ€์—ฌ๋Š” ๋งŽ์ด ํ•ด๋ดค๋‹ค.
ํ•˜์ง€๋งŒ ํŠน์ • ์กฐ๊ฑด์— ๋”ฐ๋ผ์„œ๋Š” removeEventListener๋กœ ํ•ด๋‹น ์š”์†Œ์— ๋Œ€ํ•œ ๋ถ€์—ฌ๋œ ์ด๋ฒคํŠธ๋ฅผ ์ œ๊ฑฐ๋„ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

// Modal.Vue ๋‚ด ๋ชจ๋‹ฌ์„ esc๋กœ ๋‹ซ๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง watch ์†์„ฑ
watch: {
        modelValue(newValue) {
            if (newValue) {
                window.addEventListener('keyup', this.keyupHandler)
            } else {
                window.removeEventListener('keyup', this.keyupHandler)
            }
        }
},

์œ„์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ modelValue๋กœ๋Š” App.vue์—์„œ ์ปดํฌ๋„ŒํŠธ์— ๋„˜๊ฒจ์ค€ isShow ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜จ๋‹ค.

isShow๊ฐ€ true์ด๋ฉด ๋ชจ๋‹ฌ์ด ๋ณด์—ฌ์ง„ ์ƒํƒœ์ด๋ฏ€๋กœ escํ‚ค๊ฐ€ ๋ˆ„๋ฅด๋Š” keyup ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•ด์„œ ํ•ด๋‹น key๋กœ ๋ชจ๋‹ฌ์„ ๋‹ซ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
๋ชจ๋‹ฌ์˜ ๋–  ์žˆ์ง€ ์•Š๋Š” ์ƒํƒœ์ธ๋ฐ๋„ ์ด๋ฒคํŠธ๊ฐ€ ์œ ์ง€๋˜์–ด ์žˆ์œผ๋ฉด esc๋ฅผ ๋ˆ„๋ฅผ ๋•Œ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ž‰์—ฌ ๋™์ž‘์ด ๊ณ„์†ํ•ด์„œ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.
(ex. ์ฝ˜์†”๋กœ 'esc ๋ˆ„๋ฆ„' ์ถœ๋ ฅ)

๋”ฐ๋ผ์„œ ๋ชจ๋‹ฌ์ด ๋–  ์žˆ์ง€ ์•Š์„ ๋•Œ๋Š” ์ „์ฒด window์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ๋ฅผ ์ œ๊ฑฐํ•ด์ฃผ์–ด์•ผ ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์ค„์—ฌ์„œ ํšจ์œจ์ ์ด๋‹ค.

์ด๋ฒคํŠธ๋ฅผ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์—๋งŒ ์ง‘์ค‘ํ•˜์ง€ ๋ง๊ณ  ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋ถˆํ•„์š”ํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ ์šฉ๋˜์–ด ์žˆ์ง€๋Š” ์•Š๋Š”์ง€ ์ตœ์ ํ™”๋ฅผ ๋ฐ˜๋“œ์‹œ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.



๐Ÿ‘€ ๋А๋‚€์ 

๐Ÿ‘ Keep

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

๐Ÿ˜ฑ Problem

Vue ๊ณผ์ œ๊ฐ€ ๋ฒŒ์จ ๋‚˜์˜ค๋‹ค๋‹ˆ... API๋ฅผ ํ†ตํ•ด ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ธ๋ฐ ๋ฐฐ์šธ ๋‚ด์šฉ๋„ ์ ์šฉํ•ด๋ณผ ๋‚ด์šฉ๋„ ๋„ˆ๋ฌด๋‚˜ ๋งŽ๋‹ค..

๐Ÿ˜œ Try

Vue๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ Vue ๊ณต์‹๋ฌธ์„œ์—์„œ ํ•ด๋‹น ๊ฐœ๋…์ด๋‚˜ ๊ธฐ๋Šฅ๋“ค์„ ์ •๋…ํ•ด๋ณด๋‹ˆ ์ข€ ๋” ๊ธฐ์ดˆ๊ฐ€ ํƒ„ํƒ„ํ•˜๊ฒŒ ์งœ์—ฌ์ง€๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๋Š” Reactํ•˜์ง€ ์™œ Vue ์•ˆ ์“ธ ๊ฑฐ ๋ฐฐ์šฐ์ง€ ๋ง์ž๊ณ  ํ•˜๊ฒ ์ง€๋งŒ ๋‚œ ๋ญ๋“  ๋‚˜์ค‘์— ๋‹ค ์—ฐ๊ฒฐ์ด ๋  ๊ฑฐ๋ผ ์ƒ๊ฐํ•˜๊ณ  ๊ฐœ๋…์„ ๋‹ค์ ธ๋†“์„ ์ƒ๊ฐ์ด๋‹ค. (๊ทผ๋ฐ ์‹œ๊ฐ„์ด ๋„˜ ๋งŽ์ด ๊ฑธ๋ฆฌ๊ธด ํ•œ๋‹ค... ใ…‹ใ…‹ใ…‹)



๐Ÿ˜… ํ•ด๋‹น ๋‚ด์šฉ์€ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค. ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด๋‚˜ ์˜คํ•ดํ•˜๊ณ  ์žˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด ํ”ผ๋“œ๋ฐฑ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

profile
ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ค€๋น„์ค‘...

0๊ฐœ์˜ ๋Œ“๊ธ€