본문 바로가기
공부/프론트엔드

[PJ] Vue 공부중5

by yeaseul912 2022. 10. 2.
728x90
Todo Update

submit 버튼으로 form submit 활용

 

template

<form
  @submit.prevent="onSave" >
...
  <button
    type="submit"
    class="btn btn-primary" >
    Save
  </button>
</form>

script

const onSave = async () => {
  const res = await axios.put(`http://localhost:3000/todos/${todoId}`, {
    subject: todo.value.subject,
    completed: todo.value.completed,
  });
  console.log(res);
  return { onSave };
};

res

값이 잘 바뀌었다.

 

 

 JS 객체 복사/비교

 

 js 자료형 : 원시 타입 - 값 자체 저장 , 참조 타입 - 메모리의 주소값 저장

lodash library 로 참조타입(객체) 값 비교!

 

수정시 데이터가 변동 되지 않았다면 save 버튼이 작동하지 않도록 설정

save 버튼에  todoUpdated 여부에 따른 disabled 속성 부여

 

template

<button
  type="submit"
  class="btn btn-primary"
  :disabled="todoUpdated"
>
  Save
</button>

script

import _ from "lodash";
export default {
  setup() {
  ...
  const getTodo = async () => {
      const res = await axios.get(`http://localhost:3000/todos/${todoId}`);
      // todo.value = res.data;
      // originalTodo.value = res.data; // 같은 메모리를 바라보게 됨. 값이 동시에 변경됨.
      todo.value = { ...res.data }; // spread 연산자를 사용하여 새로운 객체에 데이터 넣어줌.
      originalTodo.value = { ...res.data };
      loading.value = false;
    };
    getTodo();
    
    const todoUpdated = computed(() => {
    // 현재 todo 값과 db에 저장된 todo 값이 같은지 확인
    // 같으면 true, 다르면 false
      return _.isEqual(todo.value, originalTodo.value);
    });
    ...
    
    const onSave = async () => {
      const res = await axios.put(`http://localhost:3000/todos/${todoId}`, {
        subject: todo.value.subject,
        completed: todo.value.completed,
      });
      originalTodo.value = { ...res.data };
    };
    return {
      todo,
      loading,
      toggleTodoStatus,
      moveToTodoListPage,
      onSave,
      todoUpdated,
    };
  },
};

데이터 변경시 Save 버튼 active 됨.
Save버튼을 누르거나 데이터에 변경이 없을때 disabled 됨.

 

 

Toast 컴포넌트

bootstrap 의 alert 디자인 사용하고 props로 message와 type을 넘겨서 사용시 넘겨 받음.!

 

Toast.vue

<template>
  <div
    class="alert toast-box"
    :class="`alert-${type}`"
    role="alert"
  >
    {{ message }}
  </div>
</template>
<script>
export default {
  props: {
    message: {
      type: String,
      required: true,
    },
    type: {
      type: String,
      default: "sucess",
    },
  },
};
</script>
<style>
.toast-box {
  position: fixed;
  top: 10px;
  right: 10px;
}
</style>

template

<Toast
    v-if="showToast"
    :message="toastMessage"
    :type="toastAlertType"
/>

script

import Toast from "@/components/Toast.vue";
export default {
  components: { Toast },
  setup() {
  ...
  const showToast = ref(false);
  const toastMessage = ref("");
  const toastAlertType = ref("");
    
  const getTodo = async () => {
    try {
      const res = await axios.get(`http://localhost:3000/todos/${todoId}`);
      todo.value = { ...res.data };
      originalTodo.value = { ...res.data };
      loading.value = false;
    } catch (err) {
      triggerToast("Something went wrong", "danger");
    }
  };
  const triggerToast = (message, type = "success") => {
    toastAlertType.value = type;
    toastMessage.value = message;
    showToast.value = true;
    setTimeout(() => {
      toastAlertType.value = "";
      toastMessage.value = "";
      showToast.value = false;
    }, 3000);
  };
  
  const onSave = async () => {
    try {
      const res = await axios.put(`http://localhost:3000/todos/${todoId}`, {
        subject: todo.value.subject,
        completed: todo.value.completed,
      });
      originalTodo.value = { ...res.data };
      triggerToast("Successfully saved!");
    } catch (err) {
      triggerToast("Something went wrong", "danger");
    }
  };

...
  return {
    ...
    showToast,
    toastMessage,
    toastAlertType,
  };

실패시 alert-danger
성공시 alert-success

반응형

'공부 > 프론트엔드' 카테고리의 다른 글

[PJ] Vue 공부중7  (0) 2022.10.04
[PJ] Vue 공부중6  (0) 2022.10.03
[PJ] Vue 공부중4  (2) 2022.09.29
[PJ] Vue 공부중3  (0) 2022.09.28
[PJ] Vue 공부중2  (0) 2022.09.27

댓글