Events

자식 컴포넌트에서 부모컴포넌트로 전달

props 로 부모컴포넌트에서 자식 컴포넌트로의 데이터 전달

자식 컴포넌트 부모컴포넌트로 트리거의 목적으로 이벤트를 전달할 수 있다.

1. template 에 곧장 사용하기

<button
			class="btn btn-primary"
			@click="$emit('createPost', 1, 2, 3, '김길동')"
>

위와 같이 click 에 $emit으로 연결할 수 있다.

그러면

<PostCreate @create-post="createPost"></PostCreate>
...
const createPost = (a, b, c, d) => {
			console.log('createpost', a, b, c, d);
};

부모 메서드에서 위와 같이 선언했을 때 emit을 받아 console log를 찍는 것을 볼 수 있다.

2. setup 에서 사용하는 방법

<button class="btn btn-primary" @click="createPost">button</button>

..
<script>
setup(props, context) {
		const createPost = () => {
			context.emit('createPost', 111, 2, 3, '김길동');
		};
		return { createPost };
},
</script>

위와 같이 선언하여 context.emit를 사용하면 위로 넘겨줄 수 있다.

구조분해 할당을 진행하여 다음과 같이 바꿀 수 있다.

<button class="btn btn-primary" @click="createPost">button</button>

..
<script>
setup(props, {emit}) {
		const createPost = () => {
			emit('createPost', 111, 2, 3, '김길동');
		};
		return { createPost };
},
</script>

3.emits 옵션을 사용하여 이벤트를 선언하는 방법

emits: ['createPost'],

위와 같이 선언하면 잘 동작함을 확인할 수 있음.

4. 객체문법의 선언

emits: {
		createPost: newTitle => {
			console.log(newTitle);
			return true;
		},
},

위와 같이 사용하여 유효성 체크를 할 수 있다.

emits 안에서도 newTitle 처럼 parameter를 받을 수 있다.

emits 안에 굳이 이벤트를 선언해야하는가

선언해야한다.

  1. 가독성을 위해
  2. fallthroung 속성에서 알려진 리스너를 제외하기 위해

v-model

<input
  v-model="modelValue"
  @input="event => $emit('update:modelValue', event.target.value)"
  type="text"
/>

...
<script>
export default {
	props: ['modelValue'],
	emits: ['update:modelValue'],
	setup() {
		return {};
	},
};
</script>

위와 같은 태그가 있다.

props로 modelValue를 걸어서 v-model에 사용하였다.

부모 컴포넌트를 보자…

<LabelInputVue
  :model-value="username"
  @update:model-value="value => (username = value)"
></LabelInputVue>

...
<script>
export default {
	setup() {
		const username = ref('');
	},
};
</script>

위와 같이 username을 넘기고 있다.

그러므로 이렇게 input 태그에 값을 입력하면 username에 바인딩되는 것을 확인할 수 있다

그런데 굳이 이렇게 함수를 만들어서 사용해야할까.,,

v-model을 사용할 수 있지 않을까

<LabelInputVue v-model="username"></LabelInputVue>

이렇게 v-model을 사용하면 곧장 연결될 수 있도록 세팅되었다.

대신 자식 컴포넌트에서 v-model 과 @input 에 대해 update: 를 같이 구현해야함을 알아둘것!

Computed 사용하기

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

이런식으로 사용하여 computed로 활용할 수 있다.

전달인자를 사용하여 이름을 사용할 수 있다

<LabelTitle v-model:title="title" label="제목"></LabelTitle>

위와같이 사용하면 title로 받을 수 있다.

여러개의 v-model 만들기

<UsernameVue
  v-model:firstname="firstname"
  v-model:lastname="lastname"
></UsernameVue>

위와 같이 여러개를 만들수 있고

props: ['firstname, lastname'],
emits: ['update:firstname, update:lastname'],

위와 같이 받을 수 있다.

<LabelInputVue
  :model-value="firstname"
  @update:model-value="value => $emit('update:firstname', value)"
  label="성"
></LabelInputVue>
<LabelInputVue
  :model-value="lastname"
  @update:model-value="value => $emit('update:lastname', value)"
  label="이름"
></LabelInputVue>

그러면 위와 같이 사용할 수 있다.