[TlL๐Ÿ”ฅ] Day26(9/29)

๊น€๋‹ค์Šฌยท2021๋…„ 9์›” 30์ผ
0

Today I Learned

๋ชฉ๋ก ๋ณด๊ธฐ
22/22
post-thumbnail

Introduction

๋‚˜์˜ ๋จธ๋ฆฌ๋กœ ์Ÿ์•„์ ธ ๋“ค์–ด์˜ค๋Š” ์ง€์‹์˜ ํ™์ˆ˜ ์†์—์„œ ํ•˜๋ฃจํ•˜๋ฃจ๋ฅผ ๋ณด๋‚ด๊ณ  ์žˆ๋‹ค.
์˜ค๋Š˜์€ Vue.js ์ปดํฌ๋„ŒํŠธ์—์„œ ์ค‘์š”ํ•œ ๊ฐœ๋…์ธ props์™€ $emit์„ ๋ฐฐ์› ๋‹ค.
์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ํ™•์‹คํžˆ ์ดํ•ดํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋ณด์ž.


์˜ค๋Š˜ ์ƒˆ๋กญ๊ฒŒ ๋ฐฐ์šด ๊ฒƒ

์ปดํฌ๋„ŒํŠธ ๊ธฐ์ดˆ
1. ์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑํ•˜๊ธฐ
2. ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ๋ฐ์ดํ„ฐ ์ „๋‹ฌํ•˜๊ธฐ - props
3. ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ ์ด๋ฒคํŠธ ์ˆ˜์‹  - emit


์ปดํฌ๋„ŒํŠธ ๊ธฐ์ดˆ

์ปดํฌ๋„ŒํŠธ๋ž€ ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ ๊ฐ๊ฐ์˜ ๋…๋ฆฝ๋œ ๋ชจ๋“ˆ์„ ์˜๋ฏธํ•œ๋‹ค.
์›น ํŽ˜์ด์ง€๋ฅผ ์˜ˆ๋ฅผ ๋“ค์ž๋ฉด, ํ—ค๋”, ์‚ฌ์ด๋“œ๋ฐ”, ์ปจํ…์ธ  ๋“ฑ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑํ•˜๊ธฐ

์œ„์™€ ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ปดํฌ๋„ŒํŠธ ๋“ฑ๋ก ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.
vue์—์„œ๋Š” ์ „์—ญ(global) ๋“ฑ๋ก๊ณผ ์ง€์—ญ(local) ๋“ฑ๋ก 2๊ฐ€์ง€ ๋ฐฉ์‹์„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ „์—ญ(global) ๋“ฑ๋ก

  • ์–ธ์ œ ์–ด๋””์„œ๋“  ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ ์ „์—ญ ๋“ฑ๋ก
// main.js
import { createApp } from 'vue'
import App from '~/App'
import Hello from '~/components/Hello'

const app = createApp(App)
app.component('Hello', Hello)
app.mount('#app')

์œ„์™€ ๊ฐ™์ด Hello ๋ผ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์™€ app์— ์ „์—ญ ๋“ฑ๋กํ•˜์—ฌ app ํ…œํ”Œ๋ฆฟ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ง€์—ญ(local) ๋“ฑ๋ก

  • ํŠน์ •ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์ง€์—ญ ๋“ฑ๋ก
  • ์ฃผ๋กœ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์„ฑ ์‹œ ์ง€์—ญ ๋“ฑ๋ก์„ ๋จผ์ € ๊ณ ๋ ค
// App.vue
import Hello from '~/components/Hello'
export default {
  components: {
    Hello
  },
}

์œ„์™€ ๊ฐ™์ด Hello ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์™€ App ์ปดํฌ๋„ŒํŠธ์— ์ง€์—ญ ๋“ฑ๋กํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


์ž์‹ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ๋ฐ์ดํ„ฐ ์ „๋‹ฌํ•˜๊ธฐ

Props

  • ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ์†์„ฑ
  • ์–ด๋–ค ํŠน์ •ํ•œ ์ด๋ฆ„์œผ๋กœ ์™ธ๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ๋‚ด๋ถ€์—์„œ ํ™œ์šฉํ• ๊ฑด์ง€๋ฅผ ๊ฒฐ์ •
// Hello.vue
<template>
  <div>
    {{ hello }}
  </div>
</template>

// hello๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์™ธ๋ถ€์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๊ฒ ๋‹ค
export default {
  props: ['hello']
}

Hello๋ผ๋Š” App์˜ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ App์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ๋ฐ›๊ณ  ์‹ถ๋‹ค๋ฉด,
์œ„์™€ ๊ฐ™์ด props๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

// App.vue
<template>
  <Hello
    v-for="fruit in fruits"
    :key="fruit.id"
    :hello="fruit.name"
    />
</template>

<script>
import Hello from '~/components/Hello'
export default {
  components: {
    Hello
  },
  data(){
    return {
      fruits: [
        {id: 1, name: 'apple'},
        {id: 2, name: 'banana'},
        {id: 3, name: 'cherry'}
      ]
    }
  }
}

App ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” hello์— ์ „๋‹ฌํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ v-bind๋ฅผ ํ™œ์šฉํ•ด ์œ„์™€ ๊ฐ™์ด ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด, ๋งŒ์•ฝ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?

  • Hello๋กœ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋Š” ์™ธ๋ถ€์—์„œ ๋“ค์–ด์˜จ ๋ฐ์ดํ„ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ด๋ฏ€๋กœ ๋ฎ์–ด์“ฐ๊ธฐ ๋ฐฉ์‹์€ ์ด์šฉํ•  ์ˆ˜ ์—†๋‹ค
  • ๋”ฐ๋ผ์„œ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ emit์ด๋‹ค.


ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ ์ด๋ฒคํŠธ ์ˆ˜์‹ 

emit

  • ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ปค์Šคํ…€ ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•ด, ๋ณ€๊ฒฝ๋œ ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ ์ด๋ฒคํŠธ ์ „๋‹ฌ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•จ
// Hello.vue
<template>
  <div>
    {{ hello }}
  </div>
  <button @click="capitalize">
    Click me!
  </button>
</template>

<script>
export default {
  props: ['hello'],
  emits: ['to-upper'],
  methods: {
    capitalize(){
	   // emit์„ ์ด์šฉํ•ด to-upper๋ผ๋Š” ์ปค์Šคํ…€ ์ด๋ฒคํŠธ ์ƒ์„ฑ
      // ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€๊ฒฝ๋œ hello ๋ฐ์ดํ„ฐ ์ „๋‹ฌ 
      this.$emit('to-upper', this.hello.toUpperCase())
    }
  }
}

Hello ์ปดํฌ๋„ŒํŠธ์— ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์‹คํ–‰ ๋  ๋ฉ”์†Œ๋“œ๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.
capitalize ๋ฉ”์†Œ๋“œ๋Š” emit์„ ์ด์šฉํ•ด to-upper๋ผ๋Š” ์ปค์Šคํ…€ ์ด๋ฒคํŠธ ์ƒ์„ฑํ•˜๋ฉฐ, ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€๊ฒฝ๋œ hello ๋ฐ์ดํ„ฐ๊ฐ€ ํ•จ๊ป˜ ์ „๋‹ฌ๋œ๋‹ค.

// App.vue
<template>
  <Hello
    v-for="fruit in fruits"
    :key="fruit.id"
    :hello="fruit.name"
    @to-upper="toUpper(fruit, $event)" />
</template>

<script>
import Hello from '~/components/Hello'
export default {
  components: {
    Hello
  },
  data(){
    return {
      fruits: [
        {id: 1, name: 'apple'},
        {id: 2, name: 'banana'},
        {id: 3, name: 'cherry'}
      ]
    }
  },
  methods: {
    toUpper(fruit, upperName){
      fruit.name = upperName
    }
  }
}
</script>

App ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” to-upper ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ toUpper ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
toUpper ๋ฉ”์†Œ๋“œ๋Š” Hello ์ปดํฌ๋„ŒํŠธ์˜ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ ์‹คํ–‰ ์‹œ ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ $event๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•ด fruit.name ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.


Comment

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


์ฐธ๊ณ  ์‚ฌ์ดํŠธ

profile
์ธ์ƒ์€ ์šฉ๊ธฐ์˜ ์–‘์— ๋”ฐ๋ผ ์ค„์–ด๋“ค๊ฑฐ๋‚˜, ๋Š˜์–ด๋‚œ๋‹ค

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

comment-user-thumbnail
2021๋…„ 12์›” 29์ผ

๋‹ค์Šฌ ์™œ์ผ€ ๊ท€์—ฝ๋ƒ ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ ๋„ˆ ์ •๋ฆฌ ๋„ˆ๋ชจ ์ž˜ํ•ด์„œ ์‚ฌ๋žŒ๋“ค ๋„ˆ๊บผ ๋ณด๊ณ  ๋„์›€ ๋งŽ์ด ๋ ๋“ฏ

1๊ฐœ์˜ ๋‹ต๊ธ€