[Vue]Events

chaewonยท2024๋…„ 7์›” 22์ผ
0
post-thumbnail

๐Ÿ’ป Events

props๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ๋˜๋Š” ํŠธ๋ฆฌ๊ฑฐ์˜ ๋ชฉ์ ์œผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ฒคํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ emit ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•˜์—ฌ ๋ฐœ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•  ๋•Œ props๋กœ ์ „๋‹ฌ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์ด๋ฒคํŠธ๋ฅผ ์˜ฌ๋ฆด ๋•Œ๋Š” emit์„ ํ™œ์šฉํ•˜์—ฌ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

ํ…œํ”Œ๋ฆฟ ์•ˆ์—์„œ ์‚ฌ์šฉํ•  ๋•Œ ์ปดํฌ๋„ŒํŠธ ์ธ์Šคํ„ด์Šค์˜ ๋ฉ”์„œ๋“œ์ธ $emit์„ ์‚ฌ์šฉํ•˜์˜€๊ณ 

<template>
  <button @click="$emit('someEvent')">๋ฒ„ํŠผ</button>
</template>

๊ทธ๋Ÿฌ๋ฉด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ v-on(๋˜๋Š” @)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค.

<MyComponent @some-event="callFunction">

.once ์ˆ˜์‹์–ด๋Š” ์ปดํฌ๋„ŒํŠธ ์ปค์Šคํ…€ ์ด๋ฒคํŠธ์—์„œ๋„ ์ง€์›๋ฉ๋‹ˆ๋‹ค.

<MyComponent @some-event.once="callFunction">

์ด๋ฒคํŠธ์™€ ํ•จ๊ป˜ ํŠน์ • ๊ฐ’์„ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค. $emitํ•จ์ˆ˜ ์ด๋ฒคํŠธ๋ช…์— ์ถ”๊ฐ€๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋„˜๊ธธ ์ˆ˜ ์žˆ๋‹ค.

<template>
  <button @click="$emit('someEvent', 'Hello', 'Hi', '~')">๋ฒ„ํŠผ</button>
</template>

๊ทธ๋Ÿฐ๋‹ค์Œ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋ฒคํŠธ์™€ ํ•จ๊ป˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

<template>
	<MyComponent @some-event="callFunction" />
</template>

<script setup>
  export default{
  	setup(){
  		const callFunction = (word1, word2, word3) => {
  			alert(word1, word2, word3);
  		};
  		return {
  			callFinction
  		}
  	}
  }
</script>



์ด๋ฒคํŠธ ์„ ์–ธํ•˜๊ธฐ

emits ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฒคํŠธ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ ์ด๋ฒคํŠธ ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‘๊ฐ€์ง€ ํ˜•์‹์œผ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ฌธ์ž์—ด ๋ฐฐ์—ด ์„ ์–ธ
  • ๊ฐ์ฒด๋ฌธ๋ฒ• ์„ ์–ธ

๊ทธ๋ฆฌ๊ณ  JavaScript ์ฝ”๋“œ์—์„œ ์ด๋ฒคํŠธ๋ฅผ ๋‚ด๋ณด๋‚ผ ๋•Œ๋Š” setup() ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜์–ด์˜จ context.emit()๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฌธ์ž์—ด ๋ฐฐ์—ด ์„ ์–ธ

<script>
	export default{
  		emits: ['someEvent'],
  		setup(props, context){
  			context.emit('someEvent', 'Hello World!')
  		}
  	}
</script>
<script>
	export default{
  		emits: ['someEvent'],
  		setup(props, { emit }){
  			emit('someEvent', 'Hello World!')
  		}
  	}
</script>

๊ฐ์ฒด๋ฌธ๋ฒ• ์„ ์–ธ (์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ํ•„์š”ํ•  ๋•Œ)

  • ๊ฐ์ฒด๋ฌธ๋ฒ•์œผ๋กœ ์„ ์–ธํ•  ๊ฒฝ์šฐ validation๋กœ์ง์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ validation์ด ์—†๋‹ค๋ฉด null๋กœ ์„ค์ •ํ•˜๋ฉด ๋œ๋‹ค.
<script>
	export default{
  		emits: {
  			//์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์—†๋Š” ์ด๋ฒคํŠธ ์„ ์–ธ
  			someEvent: null,
  
  			//์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์žˆ๋Š” ์ด๋ฒคํŠธ ์„ ์–ธ
  			someSubmit: (result) => {
  				if (email && password) {
  					return true
  				} else {
  					console.warn('result ๊ฐ’์ด ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค!')
  					return false
  				}
  
  			}
  		},
  		setup(props, context){
  			context.emit('someEvent', 'Hello World!')
  		}
  	}
</script>

์„ ํƒ ์‚ฌํ•ญ์ด์ง€๋งŒ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ๋” ์ž˜ ๋ฌธ์„œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ์ด๋ฒคํŠธ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ๋˜ํ•œ Vue๊ฐ€ fallthrough์†์„ฑ์—์„œ ์•Œ๋ ค์ง„ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ œ์™ธํ•  ์ˆ˜ ์žˆ๋‹ค.


v-model ๋งŒ๋“ค๊ธฐ

์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“  ํ›„ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์— v-model์„ ์ ์šฉํ•˜๋ ค๋ฉด @update:modelValue์ด๋ฒคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ v-model์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๊ธฐ๋ณธ HTML ์š”์†Œ์ธ <input> ํƒœ๊ทธ์— v-model์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•œ๋‹ค.

<input v-model="username">

์œ„์— ์„ ์–ธ๋œ v-model์€ ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค.

<input :value="username" @input="username = $event.target.value">

์œ„์— ๊ธฐ๋ณธ ๋™์ž‘ ๋Œ€์‹  ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜ํ–‰ํ•œ๋‹ค.

<LabelInput :modelValue="username" @update:modelValue="newValue => username = newValue">
<!-- props๋กœ๋Š” :modelValue ์ด๋ฒคํŠธ๋กœ๋Š” @update:modelValue๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.-->

์ด <LabelInput>์„ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์˜ํ•ด์•ผํ•œ๋‹ค.

  • modelValue props๋ฅผ :value์†์„ฑ์— ๋ฐ”์ธ๋”ฉ
  • @input ์ด๋ฒคํŠธ์—์„œ ์ƒˆ @update:modelValue ์ด๋ฒคํŠธ๋กœ ๋‚ด๋ณด๋‚ธ๋‹ค.
<template>
  <label>
    {{ label }}
    <input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
  </label>
</template>

<script>
	export default{
  		props: ['modelValue', 'label'],
  		emits: ['update:modelValue'],
  	};
</script>

๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์ปดํฌ๋„ŒํŠธ์— v-model์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<LabelInput label="์ด๋ฆ„" v-model="username">

Computed ์ด์šฉํ•˜๊ธฐ

  • ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ computed๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ v-model์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
<template>
  <label>
    {{ label }}
    <input type="text" :value="value">
  </label>
</template>

<script>
  	import { computed } from 'vue';
  
	export default{
  		props: ['modelValue', 'label'],
  		emits: ['update:modelValue'],
  		setup(props, context){
  			const value = computed({
  				get() {
  					return props.modelValue;
  				},
  				set() {
  					contex.emit('update:modelValue', value);
  				},
  			});
  			return { value };
  		}
  	};
</script>

์ „๋‹ฌ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿด๋•Œ emit๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


v-model ์ „๋‹ฌ์ธ์ž

  • ๊ธฐ๋ณธ์ ์œผ๋กœ v-model์€ ์ปดํฌ๋„ŒํŠธ์—์„œ modelValue props์™€ update:modelValue์ด๋ฒคํŠธ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ „๋‹ฌ์ธ์ž(Arguments)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ์ด๋ฆ„์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
<BookComponent v-model:title="bookTitle">

์ด ๊ฒฝ์šฐ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” :title์„ ์†์„ฑ์œผ๋กœ ์ •์˜ํ•˜๊ณ  update:title๋กœ ์ด๋ฒคํŠธ๋ฅผ ๋‚ด๋ณด๋‚ด์•ผ ํ•œ๋‹ค.

<template>
  <article>
    <strong>์ฑ… ์ด๋ฆ„</strong> :
    <input type="text" :value="title" @input="$emit('update:title', $event.target.calue)" >
  </article>
</template>

<script>
	export default {
  		props: ['title'],
  		emits: ['update: title'],
  	}
</script>
profile
์˜๋ฌธ์€ '์‚ถ์˜ ์ˆ˜์ค€'์„ ๊ฒฐ์ •ํ•˜๊ณ , ์งˆ๋ฌธ์€ '์‚ถ ์ž์ฒด'๋ฅผ ๋ฐ”๊พผ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€