Vue의 props, state

jh_leitmotif·2022년 5월 6일
0

Vue

목록 보기
1/1

React처럼 vue도 props, state 개념이 있습니다.

그 전에, 한 가지 룰을 기록합니다.

컴포넌트 네이밍 규칙

vue component name should always be multi-word
// 관련 링크 : https://v2.vuejs.org/v2/style-guide/?redirect=true

Vue에서 컴포넌트는 2개 이상의 단어로 조합되어야 합니다.

그 이유는 HTML element명과의 중복을 피하기 위해, 그리고 element명은 모두 1개의 단어로 구성되어 있기 때문에 있다고 링크에 기록되어 있습니다.

그런 이유로 컴포넌트 이름은 항상 2개 이상의 단어로 조합되어야 하고, 파스칼 케이스 또는 케밥 케이스가 컨벤션으로서 사용되는데

컴포넌트 명명에는 케이스의 구분이 상관 없지만, template에 타 컴포넌트를 가져와 삽입할 때에는 케밥 케이스로 명시해야 합니다.

export default{
 name:'HelloWorld'
}

<template>
	<hello-world>
</template>

Vue - props

props를 전달할 때.

<template>
	<temp-comp title='임시컴포넌트'/> 
    	// 1
    <temp-comp v-bind:title='DynamicTitle'/> 
    	// 2
</template>

1번과 같이 정적인 값을 넘기거나, 2번처럼 state 또는 연산된 값을 동적으로 전달하는 것도 가능합니다.

v-bind는 생략이 가능하여, :title='DynamicTitle'로 작성해도 무관합니다.

props를 받을 때.

React는 함수의 인자를 받는 형태였지만, Vue는 props Object를 선언하여 전달받습니다.

export default{
 name:'temp-comp',
 props:{
 	title:String
 }
 // ... 또는
 props:['title']
}

Object 형태로도 가능하고, 배열 형태로도 받을 수 있습니다. 다만 전자의 형태가 전달받는 props의 자료형태를 지정할 수 있기 때문에 더 합리적인 방식으로 보입니다. 후자는 type : any같이, 영 신경쓰입니다.

전달받은 props를 사용해보자.

<template>
	<h1>{{ChangedTitle}}</h1>
</template>

<script>
export default{
 name:'temp-comp',
 props:{
 	title:String
 },
 setup(props){
 	const { title } = props;
    const ChangedTitle = '임시' + title;
    return {ChangedTitle}
    
 }
}
</script>

setup에 props를 파라미터로 넘겨주고 위와 같이 사용하기만 하면 됩니다.

Vue - state

Vue에서의 state는 아직 학습이 많이 필요합니다. 일단은 당장 사용하는 방식을 기록해둡니다.

<template>
	<button v-on:click='handleItem("메롱!")'> 버튼 </button>
    <div>{{selectedItem}}</div>
</template>

setup(){
	const selectedItem = '';
    
    const handleItem = (name) =>{
    	selectedItem = name;
    }
   
    return {selectedItem, handleItem}
}

composition api에서는 위와 같은 방식으로 state를 정의하고, 사용합니다. 하지만 아무리 버튼을 누른다고 해도 '메롱!' 이라는 글자는 보이지 않습니다.

<template>
	<button v-on:click='handleItem("메롱!")'> 버튼 </button>
    <div>{{item}}</div>
    <div>{{selectedItem}}</div>
</template>

setup(){
	const selectedItem = ref('');
    
    const item = computed(()=>selectedItem);
    
    const handleItem = (name) =>{
    	selectedItem = name
    }
    
    return {selectedItem,item, handleItem}
}

그를 위해 composition api에서는 ref를 지원합니다.

ref는 상태를 반응형으로 만들어주어 DOM에 변경된 값으로 항상 변경시켜줍니다.

여기에 computed를 조합해 사용할 수 있습니다.

computed?

동작에 포함된 state에 변경이 발생하면 즉시 값이 다시 연산됩니다.

더불어 위처럼 값을 return 하는 함수 형태로 작성될 수도 있고, Object로도 작성될 수 있으며 즉 getter와 setter 패턴을 사용할 수 있습니다.

<template>
	<button v-on:click='item.value="메롱!"'> 버튼 </button>
    <div>{{item}}</div>
</template>

setup(){
	const selectedItem = ref('');
    
    const item = computed({
    	get: () =>selectedItem,
        set: (name) =>selectedItem=name
    });
    

    
    return {item, handleItem}
}

이렇게, 거추장스러웠던 handleItem 함수를 없앨 수 있었습니다.

어라? Vue의 불변성?

<template>
	<button v-on:click='tempString="메롱!"'> 버튼 </button>
    <div>{{tempString}}</div>
</template>

setup(){
	const tempString = ref('');
    
    return {tempString}
}

React는 원본 객체를 변경하지 않고 변경된 값을 가진 새로운 객체로 덮어씌우는 것을 통해 불변성을 지키고 있습니다.

그런데 Vue는, 위와 같이 대입연산자를 통해 state를 변경시킬 수 있습니다.

이것이 가능한 것은 Vue에서는 state가 정의되면, 그것을 자동으로 getter, setter가 지정된 Object로 변환합니다. 그리고 Vue의 reactivity system이 변경사항을 감지해 DOM을 다시 렌더링합니다.

이러한 방식을 이용해 Vue는 불변성에 대한 문제를 해결했다고 합니다.

참고링크 : https://kr.vuejs.org/v2/guide/reactivity.html

React에 익숙해서인지, 영 께름칙(?)하지만 한편으로는 이렇기 때문에 러닝커브가 낮다고 하는 것 같기도 합니다.

다음에는

v-if, else.
v-for (item, index, key)

를 이용한 조건부 컴포넌트 렌더링을 정리할 예정입니다.

profile
Define the undefined.

0개의 댓글