React, Vue , Angular 는 보통 프론트엔드 UI 프레임워크로 묶여서 자주 언급됩니다. 사실 처음 개발을 시작할 때, 유저 수가 가장 많은 React를 선택했고 React기반의 RN 이나 Next.js를 사용해봤지만 아직 다른 UI프레임워크를 경험한 적이 없습니다. 그래서 React 다음으로 유저수가 많은 Vue의 공식문서를 통해 학습하고 간단한 TODOLIST를 만들며 느낀점을 공유하고자 합니다.
VUE 에 대해 전해 들은 장점
VUE가 쉽다는 얘기를 평소에 많이 들었습니다. 면접을 갔을 때도 생산성에 대한 질문도 많이 받았고, VUE를 쓰는 기업이라면 VUE의 생산성에 대해서 긍정적인 얘기를 합니다. 또한 React와 다른 양방향 바인딩에 대한 얘기도 많이합니다.
https://www.youtube.com/watch?v=-tVaahsXpwk&list=PLfLgtT94nNq3Br68sEe26jkOqCPK_8UQ-&index=1
또한 Vue를 쓰다 React를 쓰는 경우 리렌더링을 잡기 어렵다는 얘기도 많이 들었습니다.
하지만 React를 쓰는 입장에서 사실 생산성이란 익숙함에서 더욱 기인하지 않을까?라는 생각이 들었고, 굳이 Vue에 대해 학습할 필요성을 느끼기 보단, React를 더욱 잘 쓰는 방법이 제 관심사였습니다.
하지만 최근 들어 Vue에 대해서 경험하고자 간단하게 Todolist를 작성하면서 학습하게 되었습니다.
Vue와 React의 비교
1. 진입점
진입점의 경우에는 비슷하다고 느꼈습니다.
// react의 main.tsx
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
createRoot(document.getElementById('root')!).render(
<App />
)
// vue의 main.ts
import { createApp } from 'vue';
import './style.css';
import App from './App.vue';
createApp(App).mount('#app');
함수명이 Root와 app이 다르고 render냐 mount냐 다르지만 결국 함수들이 선언적으로 되어있고, 의도하는 바는 동일해 보입니다.
2. SFC와 JSX(TSX)
Vue의 경우에는 SFC라는 .vue로 파일이 구성되어 있고, React의 경우 컴퍼넌트를 jsx 혹은 tsx에서 사용합니다.
//App.vue
<script lang="ts">
import { defineComponent } from 'vue';
import TodoApp from './components/TodoApp.vue';
export default defineComponent({
components: {
TodoApp,
},
});
</script>
<template>
<div id="app">
<h1>Todo List</h1>
<TodoApp />
</div>
</template>
<style>
#app {
font-family: Arial, sans-serif;
text-align: center;
margin: 20px;
}
</style>
// App.tsx
import TodoApp from "./components/TodoApp";
function App() {
return (
<div>
<h1>Todo List</h1>
<TodoApp />
</div>
);
}
SFC는 Single-File Components 의 약자로 html, css, js를 하나의 컴퍼넌트에서 관리하는 Vue의 파일형식입니다.
template에서 html , script 에서 js , style에서 css를 다룹니다. 물론 별도의 module을 import하는 방식으로 css와 js를 관심사 분리할 수도 있습니다. 하지만 Vue측의 입장은 "관심사항의 분리가 파일 유형의 분리와 동일한 것이 아니다는 관점으로 바라보는 것이 중요하다"입니다. 하나의 컴퍼넌트가 명확하게 관심사가 분리가 되어있다면 , 굳이 css나 js를 따로 분리하기보다 응집되는 것 또한 매력적일 수 있기 때문입니다.
이때 style의 경우에는 scoped 태그를 적용함으로서 module.css 역할을 할 수 있게 할 수 있습니다.
3. 상태 관리
vue의 경우에는 v-model을 통한 양방향 바인딩을 지원합니다.
아래는 vue로 만든 간단한 todolist 입니다.
<script lang="ts">
import { defineComponent, ref } from 'vue';
// Todo 타입 정의
interface Todo {
id: number;
text: string;
completed: boolean;
}
export default defineComponent({
name: 'TodoApp',
setup() {
// 상태 정의
const newTodo = ref<string>(''); // 입력 필드 상태
const todos = ref<Todo[]>([]); // 투두리스트 배열
// 할 일 추가
const addTodo = () => {
if (newTodo.value.trim() === '') return;
todos.value.push({
id: Date.now(), // 고유 ID 생성
text: newTodo.value.trim(),
completed: false,
});
newTodo.value = '';
};
// 할 일 삭제
const removeTodo = (index: number) => {
todos.value.splice(index, 1);
};
// 할 일 완료/미완료 토글
const toggleComplete = (index: number) => {
todos.value[index].completed = !todos.value[index].completed;
};
return {
newTodo,
todos,
addTodo,
removeTodo,
toggleComplete,
};
},
});
</script>
<template>
<div>
<div class="input-container">
<input
type="text"
v-model="newTodo"
placeholder="할 일을 입력하세요"
@keyup.enter="addTodo"
/>
<button @click="addTodo">추가</button>
</div>
<ul>
<li
v-for="(todo, index) in todos"
:key="todo.id"
:class="{ completed: todo.completed }"
>
<span @click="toggleComplete(index)">{{ todo.text }}</span>
<button @click="removeTodo(index)">삭제</button>
</li>
</ul>
</div>
</template>
vue의 경우에는 ref나 reactive등을 활용하여 상태관리를 할 수 있습니다.
이때 v-model을 활용한 양방향 바인딩을 통해서 손쉽게 이벤트 핸들러 및 상태관리를 할 수 있습니다.
Vue를 사용하며 느낀점
vue를 사용하며 느낀점은 만약 바닐라 자바스크립트까지만 사용한 시점에서 새로운 프레임워크를 배운다면 vue가 react보다 사용이 쉽다고 느껴졌습니다. 컴퍼넌트의 경우에 매번 리랜더링되는 react와 다르게 Vue의 SFC파일은 변경된 상태에 대해서만 감지하여 최적화 측면에서도 수월한 점이 존재하다고 느꼈습니다.
하지만 사용 유저가 많다는 커뮤니티적인 장점도 존재하고, 익숙함이 존재하는 시점에서 제게는 React가 더 쉽게 느껴졌습니다. Vue만의 독특한 문법들도 많이 존재하였습니다. 새로 배우는 입장에서 외울게 많다는 게 비용으로 느껴졌고, 좀 더 javascript 답게 코드를 작성할 수 있는 것은 React라는 느낌을 받았습니다.
또한 오픈소스의 양적 측면에서도 React가 유리하다고 느꼈습니다.
다만 React와 Vue의 공식문서를 읽으면서 css의 중첩을 막기 위해 module이나 css-in-js를 사용하여 지역단위로 css를 적용하는 방식이나 사이드 이펙트를 감지하기 위해서 watcher 혹은 useEffect를 사용하는 방식이 결국 프레임워크는 도구나 사용법의 차이지 도달하는 방향은 유사하다는 느낌을 받았습니다.
'프론트엔드' 카테고리의 다른 글
전역상태관리 라이브러리 Jotai의 WeakMap을 활용한 메모리 최적화 (0) | 2024.09.19 |
---|---|
Three.js 튜토리얼 - 기본 구조와 사용 방법 (0) | 2024.04.10 |
(React)컴파운드 패턴으로 드롭다운 컴퍼넌트 만들기-1 구현하기 (0) | 2024.03.28 |
React에 StoryBook 도입하기(tailwind) (0) | 2024.02.23 |
DOM과 Virtual DOM (0) | 2024.02.22 |