티스토리 뷰
👏 컴포넌트 분리하기
컴포넌트 분리하기에 앞서 Vue는 Vue의 Template문법 + HTML, React는 JSX 문법으로 UI를 작성하게 됩니다.
해당 예제는
Vue : https://github.com/baegofda/blog-vue
React: https://github.com/baegofda/blog-react
위의 주소에서 데모와 함께 소스코드 확인이 가능합니다!
1. 컴포넌트 분리하기 (Button)
가장 기본적이면서도 중요한 컴포넌트를 먼저 분리해보도록 하겠습니다.
먼저 버튼(Button) 컴포넌트를 분리합니다.
React
// Button.jsx
import React from "react";
import styled from "styled-components";
const Button = ({ type, name, onClick }) => {
return (
<Btn type={type} onClick={onClick}>
{name}
</Btn>
);
}
const Btn = styled.button`
background-color: transparent;
border: 1px solid rgba(0, 0, 0, 0.6);
border-radius: 3px;
&:hover {
cursor: pointer;
}
`;
export default Button;
Button 컴포넌트는 props로 type과 onClick 이벤트, name을 받을 수 있도록 하고 css는 styled-components를 아래에 선언하여 css를 작성합니다.
이때 onClick 이벤트는 부모 컴포넌트에서 함수를 props로 받은걸 사용하여 값을 반환합니다.
Vue
<!--Button.vue-->
<template>
<button class="btn" :type="type">{{ name }}</button>
</template>
<script>
export default {
name: "Button",
props: {
type: String,
name: String,
},
};
</script>
<style scoped>
.btn {
background-color: transparent;
border: 1px solid rgba(0, 0, 0, 0.6);
border-radius: 3px;
}
.btn:hover {
cursor: pointer;
}
</style>
Vue도 비슷하게 type와 name은 props로 받으나 click 이벤트 경우엔 Vue의 emit을 이용하여 부모의 컴포넌트에 값을 보내줍니다.
css는 하단의 style 태그 내부에 작성을 하며, 해당 css들이 현재 컴포넌트 내부에만 적용되도록 scoped를 사용합니다.
2. 컴포넌트 분리하기 (TodoItem)
투두리스트 작성 시 나오는 리스트(TodoItem) 컴포넌트를 분리합니다.
React
// ToDoItem.jsx
import React from "react";
import styled from "styled-components";
import Button from "./Button";
const ToDoItem = ({ item, onComplete, onDelete }) => {
return (
<Item>
<CheckBox
type="checkbox"
defaultChecked={item.isCompleted}
onChange={() => onComplete(item.id)}
/>
<Content isCompleted={item.isCompleted}>{item.content}</Content>
<Button type="button" name="삭제하기" onClick={() => onDelete(item.id)} />
</Item>
);
};
const Item = styled.li`
display: flex;
width: 100%;
height: 40px;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
`;
const CheckBox = styled.input`
width: 20px;
height: 100%;
margin-right: 5px;
`;
const Content = styled.p`
margin-right: 5px;
line-height: 40px;
border-bottom: 1px solid rgba(0, 0, 0, 0.11);
flex: 1;
${({ isCompleted }) =>
isCompleted &&
`
color: rgba(0, 0, 0, 0.3);
text-decoration: line-through;
`}
`;
export default ToDoItem;
TodoItem의 props로는 리스트의 데이터인 item과 item의 체크 여부를 위한 onComplete 이벤트를 받고 삭제를 위한 onDelete를 부모 컴포넌트에서 props로 받습니다.
Vue
<!--ToDoItem.vue-->
<template>
<li class="item">
<input
type="checkbox"
class="item__checkbox"
@change="$emit('onComplete', todo.id)"
/>
<p
class="item__content"
:class="{ 'item__content--completed': todo.isCompleted }"
>
{{ todo.content }}
</p>
<Button type="button" name="삭제하기" @click="$emit('onDelete', todo.id)" />
</li>
</template>
<script>
import Button from "./Button.vue";
export default {
components: {
Button,
},
props: {
todo: Object,
},
};
</script>
<style scoped>
.item {
display: flex;
width: 100%;
height: 40px;
margin-bottom: 10px;
}
.item:last-child {
margin-bottom: 0;
}
.item__checkbox {
width: 20px;
height: 100%;
margin-right: 5px;
}
.item__content {
margin-right: 5px;
line-height: 40px;
border-bottom: 1px solid rgba(0, 0, 0, 0.11);
flex: 1;
}
.item__content--completed {
color: rgba(0, 0, 0, 0.3);
text-decoration: line-through;
}
</style>
Vue 또한 props로는 리스트의 데이터인 todo를 부모 컴포넌트에서 props로 받지만 체크 여부를 위한 onComplete와 onDelete는 emit을 이용하여 부모 컴포넌트로 데이터를 전달합니다.
2022.02.01 - [Vue] - 🔨 TODO ! - 컴포넌트 분리하기 (feat. 상태관리(state), function)
'Vue' 카테고리의 다른 글
🙌 Vue Custom Snippets 만들기 (2) | 2022.02.06 |
---|---|
🔨 TODO ! - 컴포넌트 분리하기 (feat. 상태관리(state), function) (0) | 2022.02.01 |
📝 TODO ! - 컴포넌트 import, state 선언 (1) | 2021.12.23 |
📒 TODO ! - 형태 알아가기 (0) | 2021.12.20 |
👏 Vue 시작하기 ! (0) | 2021.12.19 |
- Total
- Today
- Yesterday
- 프론트엔드면접
- 프론트엔드
- 프론트엔드회고
- font-family
- baegofda
- INPUT
- cssom
- 공공데이터포털
- CORS
- function
- vue예제
- 오물오물
- axios
- vue입문
- CSS
- vue3
- 공공데이터
- HTML
- react
- vue
- inline
- 프론트엔드개발자
- postman
- 노드JS
- JavaScript
- 생활코딩
- nodejs
- 리액트
- 개발자회고
- VanillaJS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 | 31 |