TIL53. Vue 데이터 보내기

조연정·2020년 12월 1일
0

Vue에서 자식에게 부모에게 데이터를 보내는 경우에 대해 알아보자.

자식 컴포넌트에 데이터 보내기(with props)

부모에서 자식으로 데이터를 전달하기 위해서 props를 사용한다. 데이터를 받을 자식 컴포넌트에 props를 선언해준다.
props에 받은 값을 data, methods 다른 곳에서 직접적으로 바꿔주어 사용하면 안된다. 이 내용은 아래 emit을 통해 다뤄보자.

// Child.vue
<template>
	<div>
    	<h1>{{title}}</h1>
    </div>  
</template>

<script>
export default {
    // 기본적인 형태 => props: ['title'],
    //대부분 사용되는 형태
    props: {
    	title: {
        	type:String,
            required: true
            }
     },
    data() {
    	return {
        	name: 'yeon-jeong',
        }
      },

}
</script>

데이터를 받을 자식 컴포넌트에 'title'를 props로 받을 것이라고 선언해주었다.

  • type: props의 type을 지정해줄 수 있다. 지정해놓은 타입이외의 값은 받을 수 없다.
  • required: props의 required 여부를 지정해줄 수 있다.(boolean값) 'true'일 때 값을 보내주지 않으면 에러를 띄운다.
// Parent.vue
<template>
	<div>
    	<h1>This is parent component.</h1>
        <Child title="title1"/>
    </div>  
</template>

<script>
import Child from './components/Child.vue';

export default {
	component: {
    	Child
    }
 }
</script>

자식 컴포넌트 태그 안에 'title' props에 원하는 값을 넣어준다.

부모 컴포넌트에 데이터 보내기(with emit)

위에서 언급했듯이 데이터 흐름이 꼬일 수 있기때문에 부모와 자식 간에는 단방향 바인딩만 가능하다. 자식은 부모의 데이터에 접근하거나 직접적으로 데이터를 변경할 수 없다.
emit은 자식이 부모에게 데이터를 전달하기 위해서 이벤트를 발생시키는 것이다.

// inputField.vue
<template>
  <div>
    <label>Name</label>
    <!-- 자식에서 부모로 데이터를 넘겨줄 때 -->
    <input type="text" :value="name" @keyup="updateName" />
  </div>
</template>

<script>
export default {
  props: {
    name: {
      type: String,
      required: true,
    },
  },
  methods: {
    updateName(e) {
      // 부모로 올리고 싶은 값 넣어주기
      this.$emit("update-name", e.target.value);
    },
  },
};
</script>

emit은 이벤트를 방출하는 컴포넌트에 선언해준다. 첫번째 인자로 원하는 이벤트이름을, 두번째 인자로 올리고 싶은 값을 넣어준다.

//parent.vue
<template>
  <div>
    <h1>This is parent2</h1>
    <form>
      <InputField :name="name" @update-name="updateName" />
      <br /><button>Submit</button>
    </form>
    {{ name }}
  </div>
</template>

<script>
import InputField from "./InputField";
export default {
  components: {
    InputField,
  },
  data() {
    return {
      name: "",
    };
  },
  methods: {
    updateName(name) {
      this.name = name;
    },
  },
};
</script>

* camelCase VS kebab-case

html속성은 대소문자를 구분하지 않기때문에 템플릿을 사용할 때 camelCased prop 이름에 해당하는 kebab-case를 사용해야 한다.

Vue.component('child', {
  // JavaScript는 camelCase
  props: ['myMessage'],
  template: '<span>{{ myMessage }}</span>'
})

//<HTML은 kebab-case>
<child my-message="안녕하세요"></child>
profile
Lv.1🌷

0개의 댓글