티스토리 뷰
👏 컴포넌트 분리하기
컴포넌트 분리하기에 앞서 Vue는 Vue의 Template문법 + HTML, React는 JSX 문법으로 UI를 작성하게 됩니다.
해당 예제는
Vue : https://github.com/baegofda/blog-vue
React: https://github.com/baegofda/blog-react
위의 주소에서 데모와 함께 소스코드 확인이 가능합니다!
1. 상태 관리(state)
상태 관리를 위한 state를 선언하겠습니다.
React에서는 React Hooks에서 제공하는 useRef, useState를 이용하여 state들을 관리합니다.
React
인풋의 값을 참조하기 위해 useRef()를 이용하여 Input에 ref={inputRef}를 선언합니다.
또 인풋 값을 바인딩하기 위한 inputText와 투두 리스트들을 담기 위한 items를 useState를 선언합니다.
import React, { useRef, useState } from "react";
import styled from "styled-components";
import Button from "../components/Button";
import ToDoItem from "../components/ToDoItem";
const ToDos = () => {
const inputRef = useRef();
const [inputText, setInputText] = useState("");
const [items, setItems] = useState([]);
//functions
return (
<Wrapper>
<Title>TODO</Title>
<Form>
<Input
ref={inputRef}
value={inputText}
type="text"
onChange={onChange}
placeholder="추가할 리스트를 입력하여 주세요 !"
/>
<Button type="submit" name="추가하기" onClick={onClick} />
</Form>
<ul>
{items.map((item) => (
<ToDoItem
key={item.id}
item={item}
onComplete={onComplete}
onDelete={onDelete}
/>
))}
</ul>
</Wrapper>
);
};
// stlyes
export default ToDos;
Vue
Vue에서는 data() 내에 사용할 state들의 초기값들을 선언합니다.
Vue의 ref는 선언해줄 필요 없이 $refs로 바로 접근이 가능하기 때문에 Input에 ref="todoInput"으로만 선언합니다.
<template>
<main class="wrapper">
<h1 class="title">TODO</h1>
<form class="form">
<input
ref="todoInput"
type="text"
class="form__input"
placeholder="추가할 리스트를 입력하여 주세요 !"
v-model="inputText"
/>
<Button type="submit" name="추가하기" @click="onClick" />
</form>
<ul>
<ToDoItem
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@onComplete="onComplete"
@onDelete="onDelete"
/>
</ul>
</main>
</template>
<script>
import Button from "../components/Button.vue";
import ToDoItem from "../components/ToDoItem.vue";
export default {
name: "Todos",
data() {
return {
inputText: "",
todos: [],
};
},
methods: {
//methods
},
components: {
//components
},
};
</script>
<style scoped>
//styles
</style>
2. 함수 선언
React와 Vue 모두 Javascript 기반이기 때문에 함수 내에서 사용하는 문법은 큰 틀에서는 Javascript 문법으로 동일합니다.
React
React에서는 선언한 state에 값을 업데이트하기 위해서는 setState을 이용합니다.
import React, { useRef, useState } from "react";
import styled from "styled-components";
import Button from "../components/Button";
import ToDoItem from "../components/ToDoItem";
const ToDos = () => {
const inputRef = useRef();
const [inputText, setInputText] = useState("");
const [items, setItems] = useState([]);
const onChange = (e) => {
setInputText(e.target.value);
};
const onClick = (e) => {
e.preventDefault();
setItems((items) => {
const item = {
id: Date.now(),
content: inputRef.current.value,
isCompleted: false,
};
const newItems = [...items, item];
return newItems;
});
setInputText("");
inputRef.current.focus();
};
const onComplete = (id) => {
setItems((items) =>
items.map((item) => {
if (item.id === id) {
return { ...item, isCompleted: !item.isCompleted };
}
return item;
})
);
};
const onDelete = (id) => {
setItems((items) => items.filter((item) => item.id !== id));
};
return (
<Wrapper>
<Title>TODO</Title>
<Form>
<Input
ref={inputRef}
value={inputText}
type="text"
onChange={onChange}
placeholder="추가할 리스트를 입력하여 주세요 !"
/>
<Button type="submit" name="추가하기" onClick={onClick} />
</Form>
<ul>
{items.map((item) => (
<ToDoItem
key={item.id}
item={item}
onComplete={onComplete}
onDelete={onDelete}
/>
))}
</ul>
</Wrapper>
);
};
//styles
export default ToDos;
Vue
Vue에서는 사용할 function은 methods에 작성하며 this로 내부 state, function, ref 등에 접근하여 값을 업데이트합니다.
또 React에서는 onChange를 이용하여 inputText를 업데이트하고 value로 바인딩을 하여 사용하지만
vue에서는 v-model을 이용하여 inputText를 사용하게되면 업데이트와 함께 데이터 바인딩이 가능합니다.
<template>
<main class="wrapper">
<h1 class="title">TODO</h1>
<form class="form">
<input
ref="todoInput"
type="text"
class="form__input"
placeholder="추가할 리스트를 입력하여 주세요 !"
v-model="inputText"
/>
<Button type="submit" name="추가하기" @click="onClick" />
</form>
<ul>
<ToDoItem
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@onComplete="onComplete"
@onDelete="onDelete"
/>
</ul>
</main>
</template>
<script>
import Button from "../components/Button.vue";
import ToDoItem from "../components/ToDoItem.vue";
export default {
name: "Todos",
data() {
return {
inputText: "",
todos: [],
};
},
methods: {
onClick(e) {
e.preventDefault();
const todo = {
id: Date.now(),
content: this.inputText,
isCompleted: false,
};
this.todos = [...this.todos, todo];
this.inputText = "";
this.$refs.todoInput.focus();
},
onComplete(id) {
this.todos = this.todos.map((todo) => {
if (todo.id === id) {
return { ...todo, isCompleted: !todo.isCompleted };
}
return todo;
});
},
onDelete(id) {
this.todos = this.todos.filter((todo) => todo.id !== id);
},
},
components: {
//components
},
};
</script>
<style scoped>
//style
</style>
'Vue' 카테고리의 다른 글
🤔 왜 CSS Framework를 도입하였는가? (feat. Tailwind CSS & Windi CSS) (2) | 2022.02.12 |
---|---|
🙌 Vue Custom Snippets 만들기 (2) | 2022.02.06 |
🖼️ TODO ! - 컴포넌트 분리하기 (feat. component, props) (0) | 2021.12.27 |
📝 TODO ! - 컴포넌트 import, state 선언 (1) | 2021.12.23 |
📒 TODO ! - 형태 알아가기 (0) | 2021.12.20 |
- Total
- Today
- Yesterday
- vue입문
- 오물오물
- baegofda
- nodejs
- vue
- postman
- 공공데이터
- VanillaJS
- 노드JS
- react
- HTML
- 생활코딩
- cssom
- font-family
- inline
- 프론트엔드
- axios
- function
- 프론트엔드회고
- vue3
- 프론트엔드면접
- CSS
- 리액트
- vue예제
- JavaScript
- 프론트엔드개발자
- INPUT
- 공공데이터포털
- 개발자회고
- CORS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |