3depth의 양방향 바인딩
component의 3개 depth를 갖는다했을 때 처리 방법

emit, component, v-model 관계에 이어쓰는 포스팅

3DEPTH COMPONENT 양방향 바인딩

제일 부모 component: TheView.vue
가운데 component: UserName.vue
제일 자식 component: LabelInput.vue

최상단 부모component

TheView.vue

js

const firstname = ref('');
const lastname = ref('');

html


  <template>
  <p>
    Username
  </p>
  <Username v-model:firstnameProps="firstname" v-model:lastname="lastnameProps"></Username>
  {{ firstname }}{{ lastname }}  
  
</template>
  • 자식component의 props.firstnameProps, props.lastnameProps로 전달된다
  • 아무것도 지정을 안하는 경우 modelValue 이름으로 전달된다.
      // 자식 Component에게 props.modelValue로 전달된다.
      // 또한, 자식 Component는 $emit('update:modelValue')로 현재 Componet에게 값을 전달한다.
      <Username v-model="firstname"></Username>
    
  • 즉 부모 자기자신의 firstname과 자식의 props.firstnameProps를 이용하여 서로 연결된다
  • 이 경우에는 자식Componet가 $emit('update:firstnameProps')로 값을 전달한다.

그다음 부모 component

Username.vue

const props = defineProps({
  firstnameProps: String,
  lastnameProps: String,
});

//html에서 v-model을 사용하므로 아래 코드 추가
const computedFirstname = computed(
  {
    get() {
      return props.firstnameProps;
    },
    set(inputValue) {
      emit('update:firstnameProps', inputValue);
    }
  }
)
  
const emit = defineEmits({
  'update:firstnameProps': null,
  'update:lastnameProps': null,
})

  <!-- v-model 사용 -->
  <LabelInput v-model="computedFirstname" label="성"></LabelInput>
  <!-- v-mdoel을 사용안하고 그냥 사용 -->
  <LabelInput :modelValue="lastnameProps" @update:modelValue="value => $emit('update:lastnameProps',value)" label="이름"></LabelInput>

v-model사용 ,component 처럼 그냥 v-model만 선언해놓고 computed를 사용안하면 어떻게 될까?

<LabelInput v-model="firstnameProps" label="성"></LabelInput>

computed 안에서의 set()을 실행시키지 못하여 결국 emit('update:firstnameProps')를 실행못한다.
즉, 자식Component가 $emit('ùpdate:modelValue', 'test')실행하여 firstnameProps = 'test'만 실행되고 props값만 갱신된다. 결국 emit를 실행시키지 못하여 부모에게 값을 전달하지못한다.

최하위 component

LabelInput.vue

const props = defineProps({
  modelValue: String,
});

{{ label }}

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

응용

중간 Component에서 v-model:name을 줘보자

중간 Component

const computedFirstname = computed(
  {
    get() {
      return props.firstnameProps;
    },
    set(inputValue) {
      emit('update:firstnameProps', inputValue);
    }
  }
)

<LabelInput v-model:seong="computedFirstname" label="성 입력하시오"></LabelInput>
<LabelInput :modelValue="lastnameProps" @update:modelValue="value => $emit('update:lastnameProps',value)" label="이름 입력하시오"></LabelInput>

자기자신의 computedFirstname의 변수와 자식component의 seong 변수를 통하여 연결하겠다라는 뜻.

자식 component

``html

`v-model`을 사용하려면 여기서도 `computed`를 사용하면 된다

```js
const props = defineProps({
  modelValue: String,
  seong: String,
});

const emit = defineEmits({
  'update:modelValue': null,
  'update:seong':null,
})
  

참고자료: Vue3 완벽 마스터: 기초부터 실전까지 - “기본편”

소스코드 바로확인하기

댓글 쓰기