Vue.js_Component
๐ Vue.js
๐ Vue.js Component
Vue Component
- Vue์ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ ์ค ํ๋
- HTML Element๋ฅผ ํ์ฅํ์ฌ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋๋ฅผ ์บก์ํ
- Vue์ ์ปดํ์ผ๋ฌ์ ์ํด ๋์์ด ์ถ๊ฐ๋ ์ฌ์ฉ์ ์ง์ ์๋ฆฌ๋จผํธ
- Vue Component๋ Vue Instance์ด๊ธฐ๋ ํ๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ์ต์ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉ
- Life Cycle Hook ์ฌ์ฉ ๊ฐ๋ฅ
- ์ ์ญ ์ปดํฌ๋ํธ์ ์ง์ญ ์ปดํฌ๋ํธ
์ ์ญ Component
- ์ ์ญ ์ปดํฌ๋ํธ๋ฅผ ๋ฑ๋กํ๋ ค๋ฉด Vue.component( tagName, options ) ์ ์ฌ์ฉํ๋ค.
- ๊ถ์ฅํ๋ ์ปดํฌ๋ํธ ์ด๋ฆ์ ์ผ๋ฐฅ ํ๊ธฐ๋ฒ์ด๋ค ( ์ ๋ถ ์๋ฌธ์, - )
- component
์ ์ญ Component ์์
<div id="app">
<my-global></my-global>
<my-global></my-global>
</div>
<script>
Vue.component("MyGlobal", {
template: `<h2>์ ์ญ ์ปดํฌ๋ํธ์
๋๋ค.</h2>`,
});
new Vue({
el: "#app",
});
</script>
- ์ถ๋ ฅ๊ฒฐ๊ณผ
์ง์ญ Component
- ์ปดํฌ๋ํธ๋ฅผ components ์ธ์คํด์ค ์ต์ ์ผ๋ก ๋ฑ๋กํจ์ผ๋ก์จ ๋ค๋ฅธ ์ธ์คํด์ค/์ปดํฌ๋ํธ์ ๋ฒ์์์๋ง ์ฌ์ฉํ ์ ์๋ ์ปดํฌ๋ํธ
- components
์ง์ญ Component ์์
<div id="app">
<my-local></my-local>
<my-local></my-local>
</div>
<div id="app2">
<my-local></my-local>
<my-local></my-local>
</div>
<script>
new Vue({
el: "#app",
components: {
"my-local": {
template: `<h2>์ง์ญ ์ปดํฌ๋ํธ์
๋๋ค.</h2>`,
},
},
});
new Vue({
el: "#app2",
});
</script>
โappโ ์์ component๋ฅผ ๋ฑ๋กํ๊ธฐ ๋๋ฌธ์ โapp2โ์์๋ component๊ฐ ์ถ๋ ฅ๋์ง ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
- ์ถ๋ ฅ๊ฒฐ๊ณผ
Data๋ ๋ฐ๋์ ํจ์์ฌ์ผ ํ๋ค
- Data๋ ์ปดํฌ๋ํธ ์ธ์คํด์ค์ ํจ์์ฌ์ผํ๋ค.
- ๋ฐ์ ์์ ๋ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์ซ์๊ฐ ํ๋์ฉ ์ฆ๊ฐํ๋ ๊ฒ์ด๋ค.
<h2>Component Data ์ค์ต</h2>
<div id="counter">
<number-counter></number-counter>
<number-counter></number-counter>
</div>
<template id="btn">
<div>
<span>8</span>
<button @click="count++">ํด๋ฆญ</button>
</div>
</template>
<script>
Vue.component("NumberCounter", {
template: "#btn",
data() {
return {
count: 0,
};
},
});
new Vue({
el: "#counter",
});
</script>
- ์ถ๋ ฅ๊ฒฐ๊ณผ
Vue Component๊ฐ ํต์
- ์์ ( ๋ถ๋ชจ ) <-> ํ์ ( ์์ ) ์ปดํฌ๋ํธ ๊ฐ์ data ์ ๋ฌ ๋ฐฉ๋ฒ
-
๋ถ๋ชจ์์ ์์
- props๋ผ๋ ํน๋ณํ ์์ฑ์ ์ ๋ฌ ( Pass Props )
-
์์์์ ๋ถ๋ชจ
- event๋ก๋ง ์ ๋ฌ ๊ฐ๋ฅ ( Emit Event )
์์ ์ปดํฌ๋ํธ์์ ํ์ ์ปดํฌ๋ํธ๋ก data ์ ๋ฌ
- ํ์ ์ปดํฌ๋ํธ๋ ์์ ์ปดํฌ๋ํธ ๊ฐ์ ์ง์ ์ฐธ์กฐ ๋ถ๊ฐ๋ฅ
- data์ ๋ง์ฐฌ๊ฐ์ง๋ก props ์์ฑ์ ๊ฐ์ template์์ ์ฌ์ฉ ๊ฐ๋ฅ
props
<h2>Props Test</h2>
<div id="app">
<child-component propsdata="์๋
ํ์ธ์"></child-component>
</div>
<script>
// ํ์ ์ปดํฌ๋ํธ
Vue.component("ChildComponent", {
props: ["propsdata"],
template: `<span></span>`,
});
// ์์ ์ปดํฌ๋ํธ
new Vue({
el: "#app",
});
</script>
- ์ถ๋ ฅ๊ฒฐ๊ณผ
- ๋๋๋ง ๊ณผ์
- new Vue()๋ก ์์ ์ปดํฌ๋ํธ์ธ ์ธ์คํด์ค๋ฅผ ํ๋ ์์ฑ
- Vue.component()๋ฅผ ์ด์ฉํ์ฌ ํ์ ์ปดํฌ๋ํธ์ธ ChildComponent๋ฅผ ์์ฑ
-
<div id="app">
๋ด๋ถ์<child-component>
๊ฐ ์๊ธฐ ๋๋ฌธ์ ํ์ ์ปดํฌ๋ํธ๊ฐ ๋๋ค. ์ฒ์ ์์ฑํ ์ธ์คํด์ค ๊ฐ์ฒด ( Vue ) ๊ฐ #app์ ์์๋ฅผ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ๋ถ๋ชจ์ ์์ ๊ด๊ณ๊ฐ ์ฑ๋ฆฝํ๋ค. - ํ์ ์ปดํฌ๋ํธ์ props ์์ฑ์ ์ ์
['propsdata']
- html์ ์ปดํฌ๋ํธ ํ๊ทธ(child-component)๋ฅผ ์ถ๊ฐํ๋ค.
- ํ์ ์ปดํฌ๋ํธ์ v-bind ์์ฑ์ ์ฌ์ฉํ๋ฉด ์์ ์ปดํฌ๋ํธ์ data์ key์ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค. ( message ) - ๊ทธ๋ฅ ๋ฌธ์์ด์ด๋ฉด : ์ฌ์ฉ x, ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ฉด : ์ฌ์ฉ
- ์์ ์ปดํฌ๋ํธ์ message ์์ฑ ๊ฐ์ธ String ๊ฐ์ด ํ์ ์ปดํฌ๋ํธ์ propsdata๋ก ์ ๋ฌ๋๋ค.
- ํ์ ์ปดํฌ๋ํธ์ template ์์ฑ์ ์ ์๋
<span>\</span>
์๊ฒ ์ ๋ฌ๋๋ค.
๋์ props
- v-bind๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ๋ชจ์ ๋ฐ์ดํฐ์ props๋ฅผ ๋์ ์ผ๋ก ๋ฐ์ธ๋ฉ ํ ์ ์๋ค.
- ๋ฐ์ดํฐ๊ฐ ์์์์ ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค ํ์ ๋ฐ์ดํฐ๋ก๋ ์ ๋ฌ๋๋ค.
- v-bind์ ๋ํ ๋จ์ถ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๊ฐ๋จํ๋ค.
v-bind
<child v-bind:my-message="parentMsg"></child>
๋จ์ถ ๊ตฌ๋ฌธ
<child :my-message="parentMsg"></child>
- ๋์ props
<div id="app">
<child-component
v-for="(food , i) in foods"
:key="i"
:foods="food"
:msg="msg[i]"
></child-component>
</div>
<script>
Vue.component("ChildComponent", {
props: ["foods", "msg"],
template: `<h2>์ญ์ (์ด,๊ฐ) !! </h2>`,
});
new Vue({
el: "#app",
data() {
return {
foods: ["์ฌํ", "์ด์ฝ๋ฆฟ", "๊ณผ์", "์๋ฃ์"],
msg: ["์ต๊ณ ์ผ", "๋ณ๋ก์ผ", "์งฑ์ด์ผ", "๊ตณ์ด์ผ"],
};
},
});
</script>
- ์ถ๋ ฅ๊ฒฐ๊ณผ
-
๊ฐ์ฒด์ ์์ฑ ์ ๋ฌ props
- ์ค๋ธ์ ํธ์ ๋ชจ๋ ์์ฑ์ ์ ๋ฌ ํ ๊ฒฝ์ฐ, v-bind:prop-name ๋์ v-bind๋ง ์์ฑํจ์ผ๋ก์จ ๋ชจ๋ ์์ฑ์ prop์ผ๋ก ์ ๋ฌํ ์ ์๋ค.
post{
id: 1,
title: 'hello'
}
<blog-post v-bind="post"></blog-post>
// ์ ์ฝ๋๋ ์๋์ ๊ฐ์ด ๋์
<blog-post
v-bind:id="post.id"
v-bind:title="post.title"></blog-post>
- ๊ฐ์ฒด์ ์์ฑ ์ ๋ฌ props
<div id="app">
<member-view
:member="{name: 'JS', age: '44', email: 'ggg@naver.com'}"
></member-view>
</div>
<script>
Vue.component("MemberView", {
props: ["member"],
template: `<div>
<div>์ด๋ฆ : </div>
<div>๋์ด : </div>
<div>์ด๋ฆ : </div>
</div>`,
});
new Vue({
el: "#app",
});
</script>
- ์ถ๋ ฅ๊ฒฐ๊ณผ
์ฌ์ฉ์ ์ ์ ์ด๋ฒคํธ ( Custom Events )
- ์ด๋ฒคํธ ์ด๋ฆ
- ์ปดํฌ๋ํธ ๋ฐ props์๋ ๋ฌ๋ฆฌ, ์ด๋ฒคํธ๋ ์๋ ๋์๋ฌธ์ ๋ณํ์ ์ ๊ณตํ์ง ์๋๋ค.
- ๋์๋ฌธ์๋ฅผ ํผ์ฉํ๋ ๋์ ์ emitํ ์ ํํ ์ด๋ฒคํธ ์ด๋ฆ์ ์์ฑํ๋ ๊ฒ์ ๊ถ์ฅ
- v-on์ด๋ฒคํธ ๋ฆฌ์ค๋๋ ํญ์ ์๋์ผ๋ก ์๋ฌธ์ ๋ณํ๋๋ค.
- ์ด๋ฒคํธ ์ด๋ฆ์ kebab-case ( ์๋ฌธ์, - ์ฌ์ฉ ) ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ
<h2>์ฌ์ฉ์ ์ ์ ์ด๋ฒคํธ</h2>
<div id="app">
<button v-on:click="doAction">๋ฉ์ธ์ง ์ ์ก</button>
<h2></h2>
</div>
<script>
new Vue({
el: "#app",
data() {
return {
msg: "",
};
},
methods: {
doAction() {
// ์ฌ๊ธฐ์ this ๋ Vue, $๋ ์จ๊ฒจ์ ธ์๋ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์ emit์ด ์๋ค.
// ์ด๊ฒ์ด ์ด๋ฒคํธ๋ฅผ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ๋ฐ์
// ๋๋ฒ์งธ ๊ฐ์ ์ธ์๋ก ์ ๋ฌํ๋ค. ์ฌ๋ฌ๊ฐ ๊ฐ๋ฅ
this.$emit("sendMsg", "์๋
ํ์ธ์ !!!");
},
},
crated() {
// emit์ ๋ํ ๋ฐ์, ๋ฏธ๋ฆฌ ๋ฐ์ ์ค๋น๋ฅผ ํ๊ณ ์์ด์ผ ํ๋ค ( created )
// emit ์ด๋ on ์ด๋ ๋ณ์๊ฐ ์ง์ง๊ฟ์ด๋ค
// msg == '์๋
ํ์ธ์ !!!'
this.$on("sendMsg", (msg) => {
this.msg = msg;
});
},
});
</script>
- ์ถ๋ ฅ๊ฒฐ๊ณผ
ํ์์์ ์์ ์ปดํฌ๋ํธ๋ก event ์ ๋ฌ
- ํ์ ์ปดํฌ๋ํธ์์ ์์ ์ปดํฌ๋ํธ๊ฐ ์ง์ ํ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ ( $emit )
- ์ด๋ฒคํธ ๋ฐ์
- this.$emit(โ์ด๋ฒคํธ๋ช โ);
- ์์ ์ปดํฌ๋ํธ๋ ํ์ ์ปดํฌ๋ํธ๊ฐ ๋ฐ์ํ ์ด๋ฒคํธ๋ฅผ ์์ ( on )ํ์ฌ data ์ฒ๋ฆฌ
- ํ์์์ ์์๋ก data ์ ๋ฌ์ ๊ณต์์ ์ผ๋ก Vue.js ๋ ๋ค๋ฃจ์ง ์๋๋ค. ( ๋จ๋ฐฉํฅ ํต์ ์ ์ด๊ธ๋๋ฏ๋ก ). ๊ทธ๋ฌ๋ Event Bus๋ฅผ ํตํด์ ์ด๋ฒคํธ ์ธ์๋ก data๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
<h2>ํ์์์ ์์ ์ปดํฌ๋ํธ๋ก event ์ ๋ฌ</h2>
<div id="app">
<h4>์ข์ํ๋ ํํธ !!</h4>
<h2>์ด ํฌํ์ : </h2>
<subject v-on:addtotcount="addTotalCount" title="์ฝ๋ฉ"></subject>
<subject v-on:addtotcount="addTotalCount" title="์๊ณ ๋ฆฌ์ฆ"></subject>
</div>
<script>
Vue.component("Subject", {
template: `<button v-on:click="addCount"> : 8</button>`,
props: ["title"],
data: function () {
return {
count: 0,
};
},
methods: {
addCount: function () {
this.count += 1;
// ๋ถ๋ชจ v-on:์ด๋ฆ์ ํด๋นํ๋ ์ด๋ฆ์ ์ด๋ฒคํธ๋ฅผ ํธ์ถ
this.$emit("addtotcount");
},
},
});
new Vue({
el: "#app",
data: {
total: 0,
},
methods: {
addTotalCount: function () {
this.total += 1;
},
},
});
</script>
- ์ถ๋ ฅ๊ฒฐ๊ณผ