안녕하세요 상훈입니다.

Vue.js 3 - composition API 에서 특정 컴포넌트에 v-model 값을 내려주는 방법을 포스팅하도록 하겠습니다.

 

필요요소 : 부모컴포넌트, 자식컴포넌트

소스 확인(링크를 통해 작성한 내용 확인이 가능합니다)

 

Vue SFC Playground

 

play.vuejs.org

1. 부모컴포넌트

<script setup>
    import CustomInput from './CustomInput.vue'
    import {ref} from 'vue'

    const message = ref('')
</script>

<template>
  메시지: {{ message }} <br/>
  <CustomInput v-model:message="message"/>
</template>

ref 로 message 를 선언 후
v-model 과 연동하여 자식 컴포넌트에 값을 내려준다.

 

2. 자식컴포넌트

<script setup>
  const props = defineProps({
    message: String,
  })
  const emits = defineEmits(['update:message'])
  
  const updateInputs = (e, type) => {
    emits(`update:${type}`, e.target.value)
  }
</script>

<template>
  <input
    :value="message"
    @input="updateInputs($event,'message')"
  /> 
</template>

props: defineProps 로 message 값을 받아온다고 선언
emit:  props로 받아온 message키 값으로 update:message상신할 것을 선언

method: updateInputs 에서 받아온 event 를 기준으로 value 를 emit 시켜주는 것을 확인 할 수 있다.

 

 


업무 중에 이전 소스에서 emit('update:input') 이라고 선언되어있길래 처음 보고, 이해가 안되어 공식문서를 찬찬히 살펴보게 되었다.

v-model 관련하여 문서를 찾아보게 되었고, component v-model 이라는 곳에서 확인할 수 있었다.

내용은 제대로 익히기 위해 playground에서 작성하였다.

 

 

 

Component v-model | Vue.js

 

ko.vuejs.org

 

 

[VUE] 컴포넌트에 여러 개 v-model 사용하기 (props 값 바꾸기)

안녕하세요! 프뚜(프로그래머 뚜)입니다! [개발 환경] - OS: windows 10 64bit - git: 2.37.1.windows.1 - nodejs: v16.16.0 - npm: 8.15.0 - yarn: 1.22.19 - @vue/cli(vue3): 5.0.8 컴포넌트에 값을 넘길 때 props를 사용합니다. 여

ssjeong.tistory.com

 

반응형

Vue.js 공식 문서를 보고 작성한 내용입니다.

 

그간 slot 의 존재는 알고 있었지만,
컴포넌트에 대한 이해력 부족으로 + 알아보기 귀찮음으로 학습을 하지 않고 미뤄왔던 내용 중 하나였다.

Slot

 

슬롯 | Vue.js

 

ko.vuejs.org

 

1. 간단하게 생각해서 버튼 내에 작성할 내용을 대체할 수 있다고 생각하면 편하다.
2. 좀 더 나아가서, 특정 태그 내에 특정 컴포넌트 등을 삽입할 수 있다. 

 

 

1. 버튼에 slot 적용해보기

// 1. slot 을 작성한 버튼 컴포넌트
<template>
  <button type="submit">
	<slot>this is replace context</slot>
  </button>
</template>

// 2. 위에서 작성한 컴포넌트를 활용
<template>
  <!-- slot에 작성하였던 내용을 그대로 노출하게 된다. -->
  <SubmitButton />
  
  <!-- 내가 작성한 내용이 있을 경우 slot이 대체된다. -->
  <SubmitButton>저장할겁니다</SubmitButton>
</template>

작성 결과

 

2. 컴포넌트도 slot 내부에 넣을 수 있다.

// 또 다른 컴포넌트 생성
<template>
  <div>
    두 번째 컴포넌트입니다.
  </div>
</template>
// 위에서 생성한 컴포넌트를 상위 컴포넌트에서 slot내에 추가
  <SubmitButton>
    <Comp />
    저장할겁니다
  </SubmitButton>

컴포넌트가 포함된 slot

이렇게 새로운 컴포넌트를 생성하고,
Button 컴포넌트 slot 에 추가한 컴포넌트를 포함시킬 수 있습니다.

 

이상입니다.

 

해당 내용을 공부하다보니, 리액트에서 props로 내려주던 text 부분을 slot으로 교체가 가능하겠다는 생각에 도달하였다.

기존에 사용하던 props의 개수를 줄이고 좀 더 가변적이고 다양한 모습의 코드를 짜도록 노력해야겠다.

 

프로젝트 도중에 custom-emit 관련한 내용을 살펴보던 중 이렇게 slot을 발견하고 이해할 수 있어서 너무 다행이라는 생각이 듭니다.오늘도 하나 배워갑니더.

반응형

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

안녕하세요 상훈입니다. 

뷰에서 props를 계속 내려주고 또 내려주고 끝없이 내려주면 정신적으로 피폐해질 수 있습니다.

물론 간단한 토이 프로젝트일 때에는 굳이 Vuex 혹은 Reactive 를 사용할 필요가 없습니다.

그러나 어느 정도 규모가 점점 커질 수록, props를 관리하기가 힘들어지고, 그에 따라 오류가 쉽게 발생하게됩니다.

그 때 필요한것이 Reactive 입니다. Vuex의 기초단계기도 하지요.

 

1. Reactive.vue
2. component1.vue
3. component2.vue
4. store.js

이렇게 4가지 파일을 준비하겠습니다. (component2 는 값의 변화가 동시에 적용되는지 확인용입니다.)

이런 형태로 짜도록 하겠습니다.

1. Reactive.vue

//Reactive.vue == Main vue
<template>
  <div>
    <h2>Reactive</h2>
    <br />
    <h3>Component01</h3>
    <Component01 />
    <br />
    <h3>Component02</h3>
    <Component02 />
  </div>
</template>
<script>
import Component01 from "./Component01.vue";
import Component02 from "./Component02.vue";

export default {
  components: {
    Component01,
    Component02,
  },
};
</script>

 

 

2. component1.vue

// Component01.vue
<template>
  <div>
    <h2>this is comp1</h2>
    <p>{{ store.count }}</p>
    <button type="button" @click="store.increment()">+</button>
  </div>
</template>
<script>
import { store } from "./store.js";
export default {
  data() {
    return {
      store,
    };
  },
};
</script>

 

3. component2.vue

<template>
  <div>
    <h2>this is comp2</h2>
    <p>{{ store.count }}</p>
    <button type="button" @click="store.decrement()">-</button>
  </div>
</template>
<script>
import { store } from "./store.js";
export default {
  data() {
    return {
      store,
    };
  },
};
</script>

 

4. store.js

import { reactive } from 'vue';

export const store = reactive({
    count: 0,
    increment() {
        this.count++;
    },
    decrement() {
        this.count--;
    }
})

 

 

각 컴포넌트에서 props로 내려주는것 없이  > 불편함에서 해방

바로 store.jsimport 해주시고 store 객체 내의 값을 사용합니다.

1) store.count
2) store.increment()
3) store.decrement()

 

보시다시피 Reactive.vue (Main vue) 에서 props로 내려주는 것 하나 없이 컴포넌트 선언만으로도 가져와서 사용하였습니다! 🤲

 

이상입니다.

 

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

반응형

v-for에는 유용한 기능이 하나 더 있다.

v-for="(value, name, index) in MyObject"

이런식으로 적용이 가능한 점인데, value와 name은 각각 MyObject에서 valuekey를 나타낸다.

예시를 들어보자면,

MyObject = {
  title : 'the title',
  author : 'Sanghoon',
  description : 'Descriptions... This is Vue.js'
 }

MyObject가 이렇게 있을 때,

<div  v-for="(value, name, index) in MyObject">
    {{ index }}.   {{ name }}  :  {{ value }}
</div>

를 작성한다면,

0. title :  the title
1. author  :  Sanghoon
2. description : Descriptions... This is Vue.js

가 된다. 그러니까, 결국에는 json 형태의 keyvalue를 출력할 수 있다는 것이다.

 

vue.js  공식 문서. 클릭시 새창으로 이동

반응형

+ Recent posts