๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๊ฐœ๋ฐœ/Vue.js

Vue ์ปดํฌ๋„ŒํŠธ / ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ํ†ต์‹ 

by 1mj 2022. 4. 4.

Vue ์ปดํฌ๋„ŒํŠธ

์ปดํฌ๋„ŒํŠธ๋Š” ํ™”๋ฉด์˜ ์˜์—ญ์„ ์ผ์ •ํ•œ ๋‹จ์œ„๋กœ ์ชผ๊ฐœ์–ด ์žฌํ™œ์šฉ ๊ฐ€๋Šฅํ•œ ํ˜•ํƒœ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

Vue ์—์„œ ์ตœ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋Š” root ๊ณ  ์ด๋ฅผ ์‹œ์ž‘์œผ๋กœ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ํ˜•์„ฑ๋œ๋‹ค.

 

- ์ „์—ญ ์ปดํฌ๋„ŒํŠธ

์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค์—์„œ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉ, ๋ชจ๋“  ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ฃผ๋กœ ํ”Œ๋Ÿฌ๊ทธ์ธ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ ์•ฑ ์ „์—ญ์—์„œ ์‚ฌ์šฉํ•  ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

vue ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ์ „์— ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

Vue.component('component-a', { template: '<div> hello world AAA !!!</div>'})
Vue.component('component-b', { template: '<div> hello world BBB !!!</div>'})
Vue.component('component-c', { template: '<div> hello world CCC !!!</div>'})


new Vue({
    el: '#app'
})


<div id="app">
    <component-a></component-a>
    <component-b></component-b>
</div>


// ๋ Œ๋”๋ง ํ›„ ์ด์™€ ๊ฐ™์ด ๊ตฌํ˜„
<div id="app">
    <div> hello world AAA !!!</div>
    <div> hello world BBB !!!</div>
</div>

 

* root ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์žˆ๊ณ  ๊ทธ ์•ˆ์— ํƒœ๊ทธ๋“ค์ด ๋“ค์–ด๊ฐ€์•ผ ํ•จ

* ์ค„ ๋ฐ”๊ฟˆ ์—†์ด ์‚ฌ์šฉํ•˜๋ ค๋ฉด ' ', ์ค„์„ ๋ฐ”๊ฟ”๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ ค๋ฉด `` ์‚ฌ์šฉ

 

- ์ง€์—ญ ์ปดํฌ๋„ŒํŠธ

vue ์ธ์Šคํ„ด์Šค ๋‚ด์— ์ง์ ‘ ์‚ฝ์ž…ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๊ณ  ๋ถ€๋ชจ-์ž์‹ ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ํ†ต์‹ ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

ํŠน์ • ์ธ์Šคํ„ด์Šค ๋‚ด์—์„œ๋งŒ ์œ ํšจํ•˜๊ณ  ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž๋™์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

components ๋กœ ์ •์˜ํ•˜๊ณ , ์ƒ์„ฑํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ…œํ”Œ๋ฆฟ ๋‚ด์— ํƒœ๊ทธ๋กœ ์ง€์ •ํ•œ๋‹ค.

์ „์—ญ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋นŒ๋“œ์— ํฌํ•จ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํŽธ์ ์œผ๋กœ๋Š” ์ง€์—ญ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•œ๋‹ค.

 

var ComponentD = { template: '<div> hello world DDD !!!</div>' }
var ComponentE = { template: '<div> hello world EEE !!!</div>' }
var ComponentF = { template: '<div> hello world FFF !!!</div>' }


new Vue({
    el: '#app',
    components: {
        'component-d': ComponentD,
        'component-e': ComponentE
    }
})


<div id="app">
    <component-d></component-d>
    <component-e></component-e>
</div>

 


์ปดํฌ๋„ŒํŠธ ํ†ต์‹  ๋ฐฉ์‹

๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž์ฒด์˜ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ’์„ ๋ฐ”๋กœ ์ฐธ์กฐํ•  ์ˆ˜๋Š” ์—†๋‹ค.

vue๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง์ ‘์ ์ธ ํ†ต์‹ ์€ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ์ด๊ณ  ๊ฐ ์ปดํฌ๋„ŒํŠธ ๊ฐ„ ๋ฐ์ดํ„ฐ ์ด๋™์€ ๋‹จ๋ฐฉํ–ฅ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ์ง€๋งŒ, ๋ฐ˜๋Œ€๋กœ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ”๋€Œ์ง€๋Š” ์•Š๋Š”๋‹ค.

 

๋ถ€๋ชจ์—์„œ ์ž์‹์œผ๋กœ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ฆฌ๊ณ (props) ์ž์‹์—์„œ ๋ถ€๋ชจ๋กœ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์˜ฌ๋ฆฐ๋‹ค(event emit).

 

- props

์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

v-bind ๋กœ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์— ์ •์˜๋œ props ์†์„ฑ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ  props ์˜ ์—ญํ• ์€ ๋ถ€๋ชจ์˜ data ์˜์—ญ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์†์„ฑ์ด๋‹ค.

 

// ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ
<div id="app">
  <child-component v-bind:propsdata="message"></child-component> // ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์— ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” message๋ฅผ ์ „๋‹ฌ
</div>


// ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ
Vue.component("child-component", { // ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ data ์†์„ฑ์ธ message๋ฅผ propsdata๋ผ๋Š” ์†์„ฑ์œผ๋กœ ๋„˜๊ฒจ๋ฐ›์Œ
  props: ["propsdata"],
  template: '<p>{{ propsdata }}</p>'
});


// ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ
var app = new Vue({
  el: "#app",
  data: {
    message: "Hello Vue! from Parent Component"
  }
});

 

* props ๋ณ€์ˆ˜๋ช…์„ ์นด๋ฉœ ๊ธฐ๋ฒ•(myComp)์œผ๋กœ ์ •์˜ํ–ˆ๋‹ค๋ฉด html ํƒœ๊ทธ์—์„œ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ผ€๋ฐฅ ๊ธฐ๋ฒ•(my-comp)์œผ๋กœ ์„ ์–ธํ•ด์•ผ ํ•œ๋‹ค.

 

- emit

ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ input ์ด๋ฒคํŠธ์— $emit ์œผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ๋„˜๊ธด๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋Š” ๋ถ€๋ชจ์—์„œ ์ž์‹์„ ํ˜ธ์ถœํ•  ๋•Œ ์ ์„ ์ด๋ฆ„, ๋‘ ๋ฒˆ์งธ ์ธ์ž๋Š” ๋„˜๊ธธ ๊ฐ’์ด๋‹ค.

<input v-model="value" @change="updateData" />

<script>
...
    props: [
        'value',
    ],
    methods : {
    	updateData(e) {
        	this.$emit('updatedData', e.target.value)
        }
    }
</script>

 

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์ž์‹์—์„œ ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋„˜๊ธด ๋ฉ”์„œ๋“œ ์ด๋ฆ„์„ ๋ฐ”์ธ๋”ฉ ์‹œ์ผœ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ data ๋ฅผ ๋ฐ”๊ฟ”์ค€๋‹ค.

<my-component value="1" @updatedData="onChanged" />

<script>
...
	methods: {
    	onChanged(myData) {
        	this.parentData = myData
        }
    }
</script>

 

์ด๋ ‡๊ฒŒ props ์™€ emit ํ•˜๋Š” ๊ณผ์ •์„ ํ•ฉ์ณ์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋†“์€ ๊ฒƒ์ด v-model ์ด๋‹ค.

์œ„ emit ํ•˜๋Š” ์˜ˆ์ œ๋ฅผ v-model ์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋ฐ”๊พธ๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

<input v-model="value" @change="updateData" />

<script>
...
    props: [
        'value',
    ],
    methods : {
    	updateData(e) {
        	this.$emit('updatedData', e.target.value)
        }
    }
</script>

 

๋ถ€๋ชจ์—์„œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ ํƒœ๊ทธ์— v-model ์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น data ๊ฐ€ ์ž์‹์˜ props ๋กœ ๋„˜์–ด๊ฐ€๊ณ , ์ž์‹์—์„œ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋ฉด ๋„˜๊ธด ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€์ˆ˜์— ํ• ๋‹น๋œ๋‹ค.

<my-component v-model="parentData" />

 

๋ณ„๋„ ์ง€์ •์ด ์—†์„ ๊ฒฝ์šฐ ์ž์‹์˜ props๋Š” value๋กœ ์ง€์ •๋˜๊ณ , ์ž์‹์—์„œ ๋ณด๋‚ด๋Š” ์ด๋ฒคํŠธ๋Š” input ์ด๋ฒคํŠธ๊ฐ€ ์ง€์ •๋œ๋‹ค. props ๋ช…์ด๋‚˜ ์ด๋ฒคํŠธ๋ช…์„ ์ปค์Šคํ…€ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ด ๋•Œ, ์ž์‹์—์„œ ๋ฐ›๋Š” props๋Š” ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. 

 


์ฐธ๊ณ ์ž๋ฃŒ ๋ฐ ์ถœ์ฒ˜ ๐Ÿ™‡‍โ™‚๏ธ

https://jinyisland.kr/p/vue-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B0%9C%EB%85%90/

https://whitepro.tistory.com/255

https://icerabbit.tistory.com/120

 

๋Œ“๊ธ€