Vue3 - 페이지 컴포넌트에 Props 전달과 ref, reactive.. (복사/재귀함수)

Corner·2023년 1월 31일
0

Vue.js 실무

목록 보기
14/14

우선 상세 정보를 가져올 게시글에 대한 API 함수를 작성한다.

api/posts.js

export function getPostById(id) {
    return posts.find(item => item.id === parseInt(id));
}

파라미터 id값은 PostDetailView.vue페이지에서 route 값 id를 string 형태로 전달하기 때문에

int로 형변환시킨다.

PageDetailView.vue에서 API를 사용해본다.

refgetPostById()를 import 하여 선언한다.

import { getPostById } from '@/api/posts';
import { ref } from 'vue';

const form = ref({});

const fetchPost = () => {
  const data = getPostById(id);
  form.value = { ...data };
}

💡 ...data는 객체 복사를 하겠다는 의미이다. 전개연산자는 2차원 객체까지 복사 가능하나, Object.assign()를 이용한 객체 복사와 같은 문제가 있다.

2차원 객체까지 복사를 하려면 커스텀 재귀 함수를 사용하자. 이는 lodash모듈의 cloneDeep()을 이용하면 된다.

이를 테면,

const lodash = require("lodash");

const obj = {
  a: 1,
  b: {
    c: 2,
  },
  func: function () {
    return this.a;
  },
};

const newObj = lodash.cloneDeep(obj);

모듈을 사용하지않고 직접 깊은 복사하여 커스텀 재귀 함수를 직접 풀어낸다면

function deepCopy(obj) {
  if (obj === null || typeof obj !== "object") {
    return obj;
  }

  let copy = {};
  for (let key in obj) {
    copy[key] = deepCopy(obj[key]);
  }
  return copy;
}

const obj = {
  a: 1,
  b: {
    c: 2,
  },
  func: function () {
    return this.a;
  },
};

const newObj = deepCopy(obj);

인수값이 객체가 아닌 경우는 그냥 반환한다.

이런 방식이 되겠다.

우선, vue코드로 이어서

반응형 기초를 배울때 string, number는 ref로 선언

배열이나 객체와 같은 것은 reactive 함수로 선언하기도 한다.

그렇지만 여기서 form을 ref 객체로 선언했던 이유는

ref로 선언하면 장점은 ...data 처럼 한꺼번에 객체 복사를 할 수 있다.

reactive는 하나씩 속성과 값을 집어 넣어주어야 한다. (한꺼번에 넣을 경우 일반 객체 값으로 들어가며, 주소값 value를 사용할 수 없다.
한꺼번에 넣어 반응형을 상실하게 될 경우, vue Devtools에서 확인해보면 수정할 수 없어진다.

ref의 장점

  • 객체 할당 가능
  • 일관성 유지
    페이지 컴포넌트에서는 ref를 사용하는 편이다. 그렇지만 보통 회사의 컨벤션을 따르는게 맞다. 이런 방식은 어쨌든 늘 해답이 아니다.

ref의 단점

  • form.value.title, form.value.content 특정 속성 값을 넣을 때 불편함

reactive의 장점

  • form.title, form.content특정 속성 값을 넣을 때 편리함

reactive의 단점

  • 객체 할당 불가능

우선 reactive의 경우로 확인 해본다.

const id = route.params.id;

let form = reactive({});

const fetchPost = () => {
  const data = getPostById(id);
  form = { ...data }; // reactive에서 개체 복사를 하면 반응형을 상실한다.
};
fetchPost();

일반 Object 값인 것으로 확인이 된다.

그럼 reactive일 경우 어떻게 해야 반응형을 유지하는가.

form.title = data.title;
form.content = data.content;
form.createdAt = data.createdAt;

속성 값을 하나하나 넣어준다.

이렇게 하면 유지는 되지만 매번 속성 값을 하나씩 넣어주는 것은 현재 시나리오와 너무 부적합한 방식이기 때문에 ref를 사용하였다.

const form = ref({});

const fetchPost = () => {
    const data = getPostById(id);
    form.value = { ...data }; // 개체 복사
};
fetchPost();

이제 추가 시나리오를 설정해보자.

게시글 리스트 하단 영역에 게시글 미리보기를 추가해보려고 한다.


전체코드

[Github](

profile
Full-stack Engineer. email - corner3499@kakao.com,

0개의 댓글