Web Development/vue

[콜럼Vue스] <script setup>

쟤리 2024. 10. 19. 19:37
728x90
반응형

<script setup> 구문을 사용하는 방식으로 Vue 컴포넌트의 TodoList 앱을 리팩토링할 수 있음. 이 방식은 Composition API의 문법을 더 간단하게 만들어주고, 코드량을 줄여주는 장점이 있음.

  • 템플릿에서 사용하는 값
    <script setup>에서는 setup() 함수 내부에서 처리하던 변수, 함수, props 등을 별도의 리턴 없이 바로 템플릿에 사용할 수 있음.
  • 컴포넌트 등록
    기존 방식에서는 components 옵션을 사용하여 자식 컴포넌트를 등록했지만, <script setup> 구문에서는 import만으로 자동으로 템플릿에서 사용 가능함.
  • 속성과 이벤트 처리
    props와 emit도 별도의 선언 없이 자동으로 처리됨. defineProps()와 defineEmits()로 props와 이벤트를 정의할 수 있음.

 


1. App.vue

 
<template>
  <div id="app" class="container">
    <div class="card card-body bg-light">
      <h1>:: Todolist App</h1>
    </div>
    <InputTodo @add-todo="addTodo" />
    <TodoList :todoList="todoList" 
              @delete-todo="deleteTodo" 
              @toggle-completed="toggleCompleted" />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import InputTodo from './components/InputTodo.vue';
import TodoList from './components/TodoList.vue';

// todoList 상태 관리
const todoList = ref([
  { id: 1, todo: "자전거 타기", completed: false },
  { id: 2, todo: "딸과 공원 산책", completed: true },
  { id: 3, todo: "일요일 애견 카페", completed: false },
  { id: 4, todo: "Vue 원고 집필", completed: false }
]);

// todo 항목 추가
const addTodo = (todo) => {
  todoList.value.push({ id: Date.now(), todo, completed: false });
};

// todo 항목 삭제
const deleteTodo = (id) => {
  todoList.value = todoList.value.filter(item => item.id !== id);
};

// 완료 상태 토글
const toggleCompleted = (id) => {
  const todo = todoList.value.find(item => item.id === id);
  if (todo) todo.completed = !todo.completed;
};
</script>

 

2. TodoList.vue

<template>
  <ul class="list-group">
    <TodoListItem v-for="item in todoList" :key="item.id" :todoItem="item" 
                  @delete-todo="$emit('delete-todo', $event)" 
                  @toggle-completed="$emit('toggle-completed', $event)" />
  </ul>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue';
import TodoListItem from './TodoListItem.vue';

// props를 정의하여 부모로부터 데이터를 받음
const props = defineProps({
  todoList: {
    type: Array,
    required: true
  }
});

// 이벤트 정의
const emit = defineEmits(['delete-todo', 'toggle-completed']);
</script>

3. TodoListItem.vue

<template>
  <li class="list-group-item">
    <div>
      <input type="checkbox" :checked="todoItem.completed" @change="$emit('toggle-completed', todoItem.id)" />
      <span :class="{ completed: todoItem.completed }">{{ todoItem.todo }}</span>
    </div>
    <button class="btn btn-danger" @click="$emit('delete-todo', todoItem.id)">삭제</button>
  </li>
</template>

<script setup>
import { defineProps } from 'vue';

// props를 정의하여 부모로부터 데이터를 받음
const props = defineProps({
  todoItem: {
    type: Object,
    required: true
  }
});
</script>

<style scoped>
.completed {
  text-decoration: line-through;
}
</style>

4. InputTodo.vue

<template>
  <div>
    <input type="text" v-model="newTodo" placeholder="새 할 일을 입력하세요" />
    <button @click="submitTodo">추가</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { defineEmits } from 'vue';

// 새로운 할 일 입력 상태 관리
const newTodo = ref('');
const emit = defineEmits(['add-todo']);

// 새로운 todo를 추가하는 함수
const submitTodo = () => {
  if (newTodo.value.trim()) {
    emit('add-todo', newTodo.value);
    newTodo.value = '';
  }
};
</script>

주요 변경 사항:

  1. defineProps와 defineEmits:
    • props와 emit을 각각 선언하고 관리할 수 있다.
    • 기존의 props 및 emits 옵션과는 다르게, 각각 defineProps() 및 defineEmits()를 사용하여 컴팩트하게 선언할 수 있다.
  2. ref와 반응형 데이터:
    • 반응형 데이터는 모두 ref()로 선언되어 관리된다.
    • todoList, newTodo 등은 상태를 관리하는 반응형 데이터로 사용된다.
  3. 자동 컴포넌트 등록:
    • <script setup>에서는 컴포넌트를 import한 후 따로 등록하지 않아도 바로 템플릿에서 사용할 수 있다.
  4. $emit 대체:
    • 기존의 this.$emit() 방식 대신, defineEmits를 사용하여 메서드를 통해 이벤트를 발신할 수 있다.

https://jerrycodezzz.tistory.com/82

 

[콜럼Vue스] To do list 만들기 (+리팩토링 추가)

자료 : 원쌤의 vue.js 퀵스타트 이 예제는 Vue.js를 사용하여 간단한 할 일 목록(TodoList) 앱을 만드는 방법을 설명함. 사용자는 할 일을 입력하고, 추가, 완료, 삭제할 수 있으며, 각각의 할 일에 대해

jerrycodezzz.tistory.com

 

728x90
반응형

'Web Development > vue' 카테고리의 다른 글

[콜럼Vue스] 동적라우트  (0) 2024.10.21
[콜럼Vue스] Vue-router  (0) 2024.10.20
[콜럼Vue스] 생명주기 훅(Life Cycle Hook)  (0) 2024.10.19
[콜럼Vue스] Watch, WatchEffect  (0) 2024.10.18
[콜럼Vue스] Computed  (0) 2024.10.18