Frontend/vue3

컴포넌트 간 데이터 전달

dddzr 2023. 4. 19. 17:10

1. v-model

v-model 디렉티브는 부모 컴포넌트에서 자식 컴포넌트로 데이터를 양방향 바인딩 할 수 있게 해줍니다. 자식 컴포넌트에서 이벤트를 발생시켜 부모 컴포넌트에 데이터를 전달할 수 있습니다.

// Parent.vue
<template>
  <div>
    <child-component v-model="message" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent,
  },
  data() {
    return {
      message: '',
    };
  },
};
</script>

// ChildComponent.vue
<template>
  <input v-model="localMessage" />
</template>

<script>
export default {
  props: ['value'],
  data() {
    return {
      localMessage: this.value,
    };
  },
  watch: {
    localMessage(newVal) {
      this.$emit('input', newVal);
    },
  },
};
</script>

위의 코드에서 Parent.vue에서 ChildComponent를 호출할 때 v-model 디렉티브를 사용합니다. ChildComponent.vue에서는 localMessage 변수를 사용하여 자식 컴포넌트의 데이터를 다루고, watch 속성을 사용하여 localMessage 값이 변경될 때 input 이벤트를 발생시켜 Parent.vue에서 부모 컴포넌트에 데이터를 전달합니다.

 

 

 

 

2. prop

prop은 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달할 때 사용합니다.

// Parent.vue
<template>
  <div>
    <child-component :message="message" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent,
  },
  data() {
    return {
      message: 'Hello, World!',
    };
  },
};
</script>

// ChildComponent.vue
<template>
  <div>
    {{ message }}
    <button @click="emitEvent">Send Event</button>
  </div>
</template>

<script>
export default {
  //prop: ['message'],
  props: {
    message: {
      type: String,
      default: 'Hello, World!',
      required: true,
    },
  },
  methods: {
    emitEvent() {
      this.$emit('my-event', 'Data from child component.');
    },
  },
};
</script>

위의 코드에서 Parent.vue에서 ChildComponent를 호출할 때 message 속성을 사용하여 데이터를 전달합니다. ChildComponent.vue에서는 props 속성을 사용하여 message 속성을 받고 this.message를 통해 사용할 수 있습니다.

 

*

:message="message"에서 첫 번째 "message"는 자식 컴포넌트에서 정의된 props의 이름입니다. 두 번째 "message"는 부모 컴포넌트의 데이터를 전달하는데 사용되는 v-bind 속성 이름입니다.

이름이 일치하지 않더라도 데이터를 전달할 수 있습니다.

다음과 같이 v-bind 속성 이름을 "parentMessage"로 변경하여 "message"라는 이름의 prop에 데이터를 전달할 수 있습니다.

<!-- ParentComponent.vue -->
<template>
  <div>
    <ChildComponent :message="parentMessage" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent,
  },
  data() {
    return {
      parentMessage: 'Hello, World!',
    };
  },
};
</script>

<!-- ChildComponent.vue -->
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      required: true,
    },
  },
};
</script>

그러나 일반적으로 v-bind 속성 이름과 props 이름을 동일하게 작성하여 코드를 보다 읽기 쉽게 만드는 것이 좋습니다.

 

props 속성

props를 정의할 때, type, default, required 등의 속성을 사용하여 프로퍼티의 유효성 검사와 초기값 설정 등을 설정할 수 있습니다.

type: 프로퍼티의 타입을 지정합니다. 지정된 타입과 일치하지 않는 값이 전달되면 콘솔에 경고 메시지가 출력됩니다. 타입으로는 String, Number, Boolean, Array, Object, Date, Function, Symbol 등 자바스크립트 기본 타입뿐만 아니라, 커스텀 타입도 지정할 수 있습니다.

default: 프로퍼티의 초기값을 지정합니다. 부모 컴포넌트에서 해당 프로퍼티를 전달하지 않은 경우, 초기값이 사용됩니다.

required: 프로퍼티가 필수인지 여부를 지정합니다. true로 지정하면, 부모 컴포넌트에서 해당 프로퍼티를 전달하지 않으면 콘솔에 경고 메시지가 출력됩니다.

 

 

3. emit

emit은 자식 컴포넌트에서 부모 컴포넌트로 이벤트와 함께 데이터를 전달할 때 사용합니다. 

// ChildComponent.vue
<template>
  <button @click="onClick">Click me</button>
</template>

<script>
export default {
  methods: {
    onClick() {
      this.$emit('button-clicked', 'Button clicked!');
    },
  },
};
</script>

// ParentComponent.vue
<template>
  <div>
    <p>{{ message }}</p>
    <ChildComponent @button-clicked="onButtonClicked" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent,
  },
  data() {
    return {
      message: '',
    };
  },
  methods: {
    onButtonClicked(data) {
      this.message = data;
    },
  },
};
</script>

ChildComponent 컴포넌트에서 button-clicked라는 이벤트를 발생시키는 onClick 메소드가 정의되어 있습니다. 이 메소드에서 $emit 메소드를 호출하여 button-clicked 이벤트를 발생시키고, 'Button clicked!'라는 데이터를 함께 전달하고 있습니다.


ParentComponent 컴포넌트에서 ChildComponent를 사용하고 있습니다. 

ChildComponent에서 발생시킨 button-clicked 이벤트를 ParentComponent에서 @button-clicked 속성을 사용하여 이벤트 리스너를 등록하고 있습니다. 등록한 이벤트 리스너인 onButtonClicked 메소드에서는 전달받은 데이터를 message 데이터에 저장하고 있습니다.