props: 상위 컴포넌트에서 자식 컴포넌트로 데이터 전달
$emit: 자식 컴포넌트에서 상위 컴포넌트로 데이터 전달
$emit에서 전달한 데이터는 상위 컴포넌트에서 이벤트 핸들러로 지정된 메소드에 첫 번째 인자로 전달된다.
만약 첫 번째 인자로 다른 매개변수를 전달하는 상황이 발생하면 $event 키워드를 통해 해당 값을 전달할 수 있다.
컴포넌트를 등록하는 방법은 지역 컴포넌트와 전역 컴포넌트가 있다.
전역 컴포넌트
// 전역 컴포넌트 등록
const app = Vue.createApp({});
app.component('컴포넌트 이름', {
props: ["title"], // 외부에서 받을 데이터
template: `<h4>{{ title }}</h4>` // html 구조 정의
})
<!-- 컴포넌트 렌더링 -->
<blog-post title="Hello"></blog-post>
<blog-post title="Good"></blog-post>
<blog-post title="Bye"></blog-post>
전역 컴포넌트 예제
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
<upper-name
v-for="fruit in fruits"
:name="fruit.name"
:key="fruit.id"
@to-upper="toUpper(fruit, $event)"
></upper-name>
</div>
<script>
const App = {
data() {
return {
fruits: [
{ id: "1", name: "aplle" },
{ id: "2", name: "banana" },
{ id: "3", name: "cherry" },
],
};
},
methods: {
toUpper(fruit, upperName) {
console.log(upperName);
fruit.name = upperName;
},
},
};
const app = Vue.createApp(App);
// 컴포넌트 이름은 대쉬 케이스로 정의
app.component("upper-name", {
template: `<div @click="capitalize">{{ name }}</div>`, // html을 정의
props: ["name"], // 컴포넌트의 외부에서 데이터를 어떠한 이름으로 받아서 내부에서 활용할 지 정의
methods: {
capitalize() {
// this.name = this.name.toUpperCase(); // 받은 prop은 읽기 전용이라 컴포넌트 내부에서 수정 불가
this.$emit("to-upper", this.name.toUpperCase()); // 컴포넌트 내부에서 외부에 커스텀 이벤트를 생성
},
},
}); // 컴포넌트 전역 등록
const vm = app.mount("#app");
</script>
</body>
</html>