React vs Vue.js
데이터 상태 관리
// Counter.vue
<template>
<button @click="increment">{{ count }}</button>
</template>
<script>
export default {
data() {
return {
count: 1
}
},
methods: {
increment() {
this.count++
}
}
}
</script>
import { useState } from 'react'
function Counter() {
const [count, setCount] = useState(1)
const increment = () => setCount(count+1)
return (<button onClick="{increment}" >{count}</button>)
}
react에서는 일반적으로 useState를 통해 데이터 상태 관리를 합니다. useState는 튜플 형식으로 반환되며 첫번째는 변수 두번째는 변수에 접근할 수 있는 set함수라고 생각하면 될 것 같습니다.
vue는 set 함수를 통해 data에 접근하는 것이 아니라, 데이터가 선언된 해당 인스턴스 내에서는 this를 통해 자유롭게 접근할 수있습니다.
Props
// Counter.vue
<template>
<div>
<h1>{{ title }}</h1>
<button @click="increment">{{ count }}</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 1
}
},
props: {
title: String
},
methods: {
increment() {
this.count++
}
}
}
</script>
import { useState } from 'react'
function Counter({ title }) {
const [count, setCount] = useState(1)
const increment = () => setCount(count+1)
return (
<div>
<h2>{title}</h2>
<button onClick="{increment}" >{count}</button>
</div>
)
}
vue에서는 ts가 아니지만 props의 타입을 지정할 수 있습니다. 데이터와 마찬가지로 해당 인스턴스 내에서는 this를 통해 접근할 수 있습니다.
react에서는 함수의 인자로 생각하고 사용하면 됩니다.
// Button.vue
<template>
<button @click="$emit('handle-click')">
{{ value }}
</button>
</template>
<script>
export default {
props: ['value']
}
</script>
// Counter.vue
<template>
<div>
<h1>{{ title }}</h1>
<Button @handle-click="increment" :value="count" />
</div>
</template>
<script>
import Button from './Button'
export default {
components: {
Button,
},
data() {
return {
count: 1
}
},
props: ['title'],
methods: {
increment() {
this.count++
}
}
}
</script>
import { useState } from 'react'
function Button({value, handleClick}) {
return <button onClick={handleClick}>{value}</button>
}
function Counter({ title }) {
const [count, setCount] = useState(1)
const increment = () => setCount(count+1)
return (
<div>
<h2>{title}</h2>
<button handleClick="{increment}" value="{count}" />
</div>
)
}
react에서는 자식 컴포넌트에서 부모 컴포넌트의 함수를 실행하려면 props로 함수를 넘겨서 사용할 수 있습니다.
vue에서는 event.$emit()을 사용해 컴포넌트 간에 통신을 할 수 있습니다.
Slots
// Button.vue
<template>
<div>
<button @click="$emit('handle-click')">
<slot>Default</slot>
</button>
<slot name="afterButton"/>
</div>
</template>
<script>
export default {}
</script>
// Counter.vue
<template>
<div>
<h1>{{ title }}</h1>
<Button @handle-click="increment">
<strong>{{ count }}</strong>
<template v-slot:afterButton>
Some content after the button...
</template>
</Button>
</div>
</template>
<script>
import Button from './Button'
export default {
components: {
Button,
},
data() {
return {
count: 1
}
},
props: ['title'],
methods: {
increment() {
this.count++
}
}
}
</script>
import { useState } from 'react'
function Button({AfterButton, handleClick, children}) {
return (
<>
<button onClick={handleClick}>
{children}
</button>
<AfterButton />
</>
)
}
function Counter({ title }) {
const [count, setCount] = useState(1)
const increment = () => setCount(count+1)
return (
<div>
<h2>{title}</h2>
<Button value={count} handleClick={increment} AfterButton={}>
{ count }
</Button>
</div>)
}
vue의 slot기능은 react에서는 children props로 사용할 수 있다.
watch vs useEffect
// Counter.vue
<template>
<button @click="increment">{{ capitalizedTitle }}</button>
</template>
<script>
export default {
data() {
return {
count: 1
}
},
watch: {
count() {
console.log(this.count)
}
},
methods: {
increment() {
this.count++
}
}
}
</script>
import { useState, useEffect } from 'react'
function Counter({ title }) {
const [count, setCount] = useState(1)
const increment = () => setCount(count+1)
useEffect(() => {
console.log(count)
}, [count])
return (
<button onClick={increment}>{count}</button>
)
}
vue에서는 watch를 통해 값이 업데이트 되었을 때의 함수를 정의할 수 있습니다.
react에서는 useEffect라는 훅을 통해 해당 데이터에 대해 업데이트가 있을 시 의 함수를 정의할 수 있습니다.
mounted
// Counter.vue
<template>
<button @click="increment">{{ capitalizedTitle }}</button>
</template>
<script>
export default {
data() {
return {
count: 1
}
},
mounted() {
// this.$http.get...
},
methods: {
increment() {
this.count++
}
}
}
</script>
import { useState, useEffect } from 'react'
function Counter({ title }) {
const [count, setCount] = useState(1)
const increment = () => setCount(count+1)
useEffect(() => {
// ajax request...
}, [])
return (
<button onClick={increment}>{count}</button>
)
}
react에서 함수형 컴포넌트에서는 리액트 라이프사이클 함수를 사용할 수 없는데 vue에서 mounted같은 함수를 useEffect 훅의 배열을 비워둠으로써 비슷하게 사용할 수 있습니다. 이렇게 되면 렌덩링 시에 단 한번만 실행되기 때문에 mounted처럼 사용할 수 있습니다.
'Vue 스터디' 카테고리의 다른 글
[Vue.js] 사용자 정의 디렉티브 (0) | 2021.08.03 |
---|---|
[Vue.js] vue-i18n (0) | 2021.07.28 |
Vue에서 virtual DOM은?? (0) | 2021.07.16 |
Vue.js 에서 HOC(High Order Component) 만들기 (0) | 2021.07.15 |
Vue.js 라우터 네비게이션 가드 (0) | 2021.07.15 |