<div id="app">
<upper-name
v-for="fruit in fruits"
:key="fruit.id"
:fruitname="fruit.name"
></upper-name>
</div>
const App = {
data() {
return {
fruits: [
{ id: "1", name: "apple" },
{ id: "2", name: "banana" },
{ id: "3", name: "cherry" },
],
};
},
};
const app = Vue.createApp(App);
// 컴포넌트 전역 등록
app.component("upper-name", {
template: `<div>{{fruitname}}</div>`,
props: ["fruitname"],
});
const vm = app.mount("#app");
기존의 createApp을 통해 만든 최상위 App 컴포넌트는 id를 가지고 있는 html구조와 연결해서 사용했지만, 나머지 컴포넌트는 html과 연결하는 것이 아니라 내부에 로직을 직접적으로 작성하여 사용한다.
props는 특정한 컴포넌트 바깥에서 내부로 집어넣는 데이터이다.
uppername에서 보내준 데이터의 key와 value를 컴포넌트 정의한 곳에서 그대로 props로 그대로 받아 사용한다.
app.component("upper-name", {
template: `<div @click="capitalize">{{fruitname}}</div>`,
props: ["fruitname"],
methods: {
capitalize() {
this.fruitname = this.fruitname.toUpperCase();
},
},
});
컴포넌트에서 상위 컴포넌트의 fruitname 값에 접근할 때는 다음과 같은 에러가 뜬다.

뷰에서도 역시나 컴포넌트에 연결된 이벤트 로직은 상위 컴포넌트에서 해결해야한다. 여기서는 App이 된다.
이럴때 emit을 사용하여 해결할 수 있다.
<div id="app">
<upper-name
v-for="fruit in fruits"
:key="fruit.id"
:fruitname="fruit.name"
@to-upper="toUpper(fruit,$event)"
></upper-name>
</div>
const App = {
data() {
return {
fruits: [
{ id: "1", name: "apple" },
{ id: "2", name: "banana" },
{ id: "3", name: "cherry" },
],
};
},
methods: {
toUpper(fruit, upperName) {
fruit.name = upperName;
},
},
};
const app = Vue.createApp(App);
// 컴포넌트 전역 등록
app.component("upper-name", {
template: `<div @click="capitalize">{{fruitname}}</div>`,
props: ["fruitname"],
methods: {
capitalize() {
this.$emit("to-upper", this.fruitname.toUpperCase());
},
},
});
const vm = app.mount("#app");
to-upper 이벤트가 발생하면 인자의 데이터를 올려준다는 의미를 가진다.(props가 전해지는 역방향)
기본적으로, 함수 호출시에 따로 파라미터를 지정하지 않아도 이벤트 핸들러의 첫 번째 파라미터는 데이터가 되지만, 파라미터를 두개를 사용할 경우(첫 번째 파라미터로 다른 값을 받아야 하는 경우)는 마지막 인수인 $event로 데이터를 받는다.
따라서, toUpper함수 안에서 $event로 받아 인자의 데이터를 조작할 수 있다.
전체 로직을 컴포넌트 단위로 분리하여 구현하고, 해당 컴포넌트가 상위 컴포넌트에게 데이터를 전달하여 상위 컴포넌트가 조작을 하는 방향은 이전 강의에서 배운 경우와 똑같았다. 다만 Vue는 문법이 좀 덜 익숙하기도 하고 개인적으로 좀 복잡하다고 생각한 것 같다.