props, $emit

이은지·2021년 8월 30일
0
post-custom-banner

중앙관리식 데이터 관리

  • 프레젠터 컴포넌트

    그저 데이터를 보여주는

  • 컨테이너=비즈니스 로직 컴포넌트

    한 곳에서 데이터 조작이 일어나게끔

    it's like Vuex의 축소판

  • 하위 컴포넌트에서 각각 이뤄지던 할 일 데이터 추가, 삭제를 App이라는 컨테이너에서 한 번에 관리하고자 함

    TodoInput의 newTodoItem
    TodoList의 todoItems[]
    로컬 스토리지의 todoItems

    를 모두 하나로 통합
    App.vue의 todoItems로 통합할 것

  • TodoList를 예로 들면,

    원래는 새로고침을 해서 localStorage.getItem()이 실행되어야 로컬 스토리지의 데이터가 TodoList내의 todoItems[]로 옮겨져올 수 있었던 것.

    props를 통해 데이터를 받아온다는 건, 애초에 TodoList.vue 내에 App.vue의 todoItems(혹은 로컬 스토리지) 라는 부품이 끼워져 있는 것처럼 이해하면 될 듯 . 새로고침을 할 필요가 없이 바로 바뀐다.

props로 데이터 내려보내기

App.vue

<template>
	<div id="app">
	<TodoList v-bind: propsdata="todoItems"></TodoList>
        v-bind: 내려보낼 프롭스 속성 이름 = "현재 위치의 컴포넌트 데이터 속성"
	</div>
</template>

<script>
export default {
    data(){
        return{
            todoItems: []
            이 todoItems를 propsdata라는 이름으로 TodoList에 내려보낸 것
        }
    }
}
</script>

TodoList.vue

<script>
export default {
	props: ['propsdata']
}
</script>

상위 컴포넌트 - template 부분 - 하위 컴포넌트 태그 내에 v-bind로 내려보낼 데이터를 선언

하위 컴포넌트 - script 부분 - export dafault - props에서 상위 컴포넌트에서 설정한 데이터 이름으로 받기 ['상위 컴포넌트에서 설정한 프롭스 데이터 이름']

$emit으로 이벤트 올려보내기

App.vue

<template>
<TodoInput @addTodoItem="addOneItem"></TodoInput>
	<!--@하위 컴포넌트에서 발생시킨 이벤트 이름 = "현재 컴포넌트의 메소드 명"-->
	<!--하위 컴포넌트의 이벤트 발생이 메소드 실행의 조건이 됨-->
</template>

<script>
methods: {
    addOneItem(todoItem){
        //하위 컴포넌트에서 올려보낸 인자를 todoItem이라는 이름으로 받음
        var obj = {completed: false, item: todoItem};
        localStorage.setItem(todoItem, JSON.stringify(obj));
        this.todoItems.push(obj);
    }
}
</script>

TodoInput.vue

<script>
	export default {
        methods: {
            addTodo() {
                if (this.newTodoItem !== ' '){
                    this.$emit('addTodoItem', this.newTodoItem)
    // this.$emit('이벤트 이름', 인자1, 인자2, ...)
    // 하위 컴포넌트에서 발생시킨 이벤트 == 하위 컴포넌트에서 상위 컴포넌트로 보내는 신호와도 같다
                }
            }
        }
    }
</script>

상위 컴포넌트 - template 부분 - 하위 컴포넌트 태그 내에 v-on으로 받아올 이벤트와 매핑할 상위 컴포넌트 내의 메소드 선언

하위 컴포넌트 - script 부분 - export default - 메소드 내에서 $emit을 통해 상위 컴포넌트에 전달할 이멘트 명과 인자를 선언

데이터를 수정하고자 할 때 주의점

App.vue

<script>
	export default {
        methods: {
            toggleOneItem(todoItem, index){
                todoItem.completed = !todoItem.completed;
            }
        }
    }
</script>

TodoList.vue

<template>
	<div>
        <ul>
            <li v-for="(todoItem, index) in propsdata">
    ...
    		</li>
    	</ul>
    </div>
</template>

toggleOneItem의 인자인 todoItem은 props를 통해 App.vue에서 받아온 데이터임

따라서 todoItem에서 데이터를 수정하기 보다는(불필요하게 하위 컴포넌트에 내려갔다 올라오는 것이므로) 컨테이너인 App.vue에서 바로 수정하는 것이 바람직하다.

App.vue

<script>
	export default {
        methods: {
            toggleOneItem(todoItem, index){
                this.todoItems[index].completed = !this.todoItems[index].completed;
            }
        }
    }
</script>

데이터 관리는 컨테이너 컴포넌트에서만 이뤄지도록!

post-custom-banner

0개의 댓글