Vue3 Component

Vanila Js를 사용하다가 Vue를 해야겠다고 마음 먹은 가장 큰 이유가 Component이다. 컴포넌트를 활용하면 블록을 조립하듯 여러 블록을 별도로 선언해두고 필요할 때 가져와 조립할 수 있다. 이렇게하면 중복되는 코드를 줄일 수 있고, 동시에 유지보수도 편해진다. 


Component

<!--HeaderComp.vue-->
<template>
    <header>...</header>
</template>

헤더 부분을 작성해 별도의 vue 파일을 만든다. 그리고 이 코드를 다른 vue 파일에서 재활용할 수 있다. 

<!--App.vue-->
<template>
  <HeaderComp></HeaderComp>
</template>

<script>
import HeaderComp from "./components/HeaderComp.vue"

export default {
  name: 'App',
  components: {
    HeaderComp
  }
}
</script>

해당 vue 파일을 import한 후, components에 등록한다. 그러면 <컴포넌트></컴포넌트> 형태로 활용할 수 있다. 


props

함수의 재활용을 위해 파라미터를 사용하듯, 컴포넌트에서는 props를 통해 데이터를 넘겨줄 수 있다. 

<!--TestComp.vue-->
<template>
    <div>{{para}}</div>
</template>

<script>
export default {
    props: {
        para: {
            type: Number,
            default: 0
        }
    }
}
</script>

props에 사용할 파라미터를 선언해준다. 이때 데이터 타입이나 기본값을 지정할 수 있다. 

<!--App.vue-->
<template>
  <TestComp :para="10"></TestComp>
</template>

<script>
import TestComp from "./components/TestComp.vue"

export default {
  name: 'App',
  components: {
    TestComp
  }
}
</script>

그리고 컴포넌트를 불러와 사용하는 쪽에서 :파라미터 형식의 태그를 작성해 값을 넘겨준다. 


전역 컴포넌트

컴포넌트를 사용할 때마다 import를 해오는 것은 불편하다. main.js는 프로젝트의 전역을 담당하고 있기 때문에 이곳에 .component("이름", 컴포넌트) 형태로 등록해주면 다른 파일에서 별도의 import 없이 사용할 수 있다. 

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import TestComp from "./components/TestComp.vue"

const app = createApp(App)

app.component("TestComp", TestComp)

app.mount('#app')

자식 컴포넌트에서 부모로

위 방법은 부모 컴포넌트에서 자식 컴포넌트로 정보를 전달했다면 반대도 가능하다. 큰 과정은 아래와 같다. 

(자식) 신호 + 데이터 → (부모) 함수 실행

<template>
    <button @click="add">add One</button>
</template>

<script>
let a = 0;
export default {
    methods: {
        add() {
            a += 1;
            this.$emit("fromChild", a)
        }
    }
}
</script>

여기서 특별한 함수는 $emit이다. this.$emit("신호이름", 데이터1, 데이터2...) 형태로 부모 컴포넌트에 신호를 보낸다.

<template>
  <div>{{num}}</div>
  <TestComp @fromChild="update"></TestComp>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      num: 0
    }
  },
  methods: {
    update(a) {
      this.num = a;
    }
  },
}
</script>

부모 측에서는 @신호="실행할 함수"의 형태로 특정 신호가 감지되면 설정한 함수를 실행하도록 한다. 그리고 자식에서 전달한 데이터들이 함수의 파라미터로 전달된다.