데이터를 주고 받는 두 가지 방식 - router와 pinia

김규연·2024년 4월 8일
1

Vue

목록 보기
2/7

🧐 글 작성 계기

vue3를 통해 데이터를 주고 받는 작업을 하는 도중 데이터를 주고 받는 방식이 두 가지가 있다는 것을 알게 되었다. 두 가지 방법 말고 다른 여러 가지 방법이 있겠지만 필자는 두 가지 방식에 대해서만 이 글에서 다룰 것이다.

📒 router.push

장점

  • 가년하고 직관적이다. 필요한 데이터를 직접 넘기기 때문에 구현이 간단하다.
  • url 쿼리 파라미터로 데이터를 전달하기 때문에 브러우저 히스토리에 데이터가 남아 사용자가 뒤로가기 버튼을 통해 이전 데이터에 다시 접근할 수 있다.

단점

  • url의 쿼리 파라미터로 데이터를 전달하기 때문에 보안에 취약할 수 있다. 중요한 정보가 노출될 수 있다.
  • 대부분의 경우 url의 길이에 제한이 있으므로 큰 데이터를 전달하기 어려울 수 있다.

💻 사용예시

등록페이지에서 목록페이지로 데이터를 보내는 작업을 진행했다. /greetings는 목록페이지이고 formData에는 목록페이지에 보낼 데이터가 리스트 형식으로 들어가 있다.

<script setup lang="ts">
  import { ref } from 'vue';

  const router = useRouter();

  const formData = ref({
    id: '',
    name: '',
    password: '',
    conformPassword: '',
    sc: '',
    phone: '',
    email: '',
    department: '',
    address: '',
  });

const onSignUp = () => {
  router.push({
    path: '/greetings',
    query: { formData: JSON.stringify(formData.value) },
  });
};

  ...
</script>

template에 input들 중 일부만 표시하자면 아래와 같이 되어 있다.

<template>
  ...
  
  <div class="q-gutter-md row">
    <div class="col">
      <q-input
      v-model="formData.id"
      label="아이디"
      :rules="idRules"
      lazy-rules
      />
    </div>
    <div class="col">
      <q-input
      v-model="formData.name"
      label="이름"
      class="q-mb-md"
      :rules="nameRules"
      lazy-rules
      />
     </div>
  </div>
  
  ...
</template>

목록 페이지 중 일부만 표시한걸로 등록 페이지에서 받은 데이터들 처리는 아래와 같이 했다.

<script setup lang="ts">
  ...

  let formDataString = route.query.formData as string | null;
  let formData = formDataString ? JSON.parse(formDataString) : null;

  const rows = ref([formData]);

  ...
</script>

이 방법은 Vue Router의 'router.push'함수를 사용하여 다음페이지로 데이터를 전달한다. 데이터는 url의 쿼리 파라미터로 전달되며, 여기서 'formData'변수의 값을 JSON 문자열로 변환하여 전달하고 있다.

📒 pinia

pinia란?

pinia는 vue.js 애플리케이션의 상태관리 라이브러리 중 하나이다. vuex와 비슷한 역할을 하지만 몇 가지 다른 디자인 선택과 함께 제공된다.
pinia는 상테를 중앙 집중화된 저장소에 저장하는 vuex와 달리 분산 저장소를 사용한다. 이는 pinia가 vuex보다 더 가벼우며, 대규모 어플리케이션에서 상태관리를 더 효휼적으로 할 수 있도록 도와준다. 또한 vue3의 Composition API와 완벽하게 통합되어 사용자가 코드를 보다 모듈화하고 재사용 가능한 상태로직을 작성할 수 있다.
pinia는 반응형 상태를 사용하여 상태 변경에 대한 반응을 쉽게 처리할 수 있다. 또한 TypeScript를 완전히 지원하여 타입 안정성을 보장한다.
이러한 특징들은 pinia를 vue.js 어플리케이션의 상태관리에유연하고 효율적인 솔루션으로 만들어준다.

장점

  • 상태 관리 라이버리를 사용하여 데이터를 효율적으로 관리할 수 있다.
  • pinia는 vues와 유사한 상태 관리 기능을 제공하며, 상태의 중앙 집중 관리와 상태 변경 추적 등을 지원한다.

단점

  • 상태 관리 라이브러리를 도입하고 사용하는 과정이 있어 구현이 조금 복잡할 수 있다.
  • 브라우저 히스토리에 데이터가 남지 않기 때문에 사용자가 뒤로가기 버튼을 통해 이전 데이터에 접근할 수 없다.

💻 사용예시

pinia를 사용하려면 stores에서 설정을 해주어야 한다.
stores/use-sign-up-stoer.ts

import { defineStore } from 'pinia';

export const useSignUpStore = defineStore('signup', {
  state: () => ({
    signUpInfo: null as ISignUpInfo | null,
  }),
  actions: {
    setSignUpInfo(info: ISignUpInfo) {
      this.signUpInfo = info;
    },
  },
});

ISginUpInfo의 type들은 아래와 같다.

interface IOption {
  label: string;
  option: string;
}

interface ISignUpInfo {
  id: string;
  name: string;
  confirmPassword: string;
  password: string;
  phone: string;
  email: string;
  sc: string;
  department: IOption;
  address: string;
}

등록페이지의 input은 아래와 같으며 일부만 작성했다.

<template>
  ...

  <div class="q-gutter-md row">
    <div class="col">
    	<q-input v-model="id" label="아이디" :rules="idRules" lazy-rules />
    </div>
    <div class="col">
      <q-input
      v-model="name"
      label="이름"
      class="q-mb-md"
      :rules="nameRules"
      lazy-rules
      />
    </div>
  </div>  

  ...
</template>

pinia를 이용해서 데이터를 보내는 방법은 다음과 같다.

<script setup lang="ts">
  ...

  import { useRouter } from 'vue-router';
  import { useSignUpStore } from 'src/stores/use-sign-up-store';

  const signUpStore = useSignUpStore();
  const router = useRouter();

  const saveSingUpInfo = () => {
    const info: ISignUpInfo = {
      id: id.value,
      name: name.value,
      confirmPassword: confirmPassword.value,
      password: password.value,
      phone: phone.value,
      email: email.value,
      sc: sc.value,
      department: department.value,
      address: address.value,
    };
    signUpStore.setSignUpInfo(info);
    router.push('/greetings');
  };

  ...
</script>

pinia를 이용해서 데이터를 받는 방법은 다음과 같다.

<script setup lang="ts">
  ...

  import { ref } from 'vue';
  import { useSignUpStore } from 'src/stores/use-sign-up-store';
  import { storeToRefs } from 'pinia';

  const signUpStore = useSignUpStore();
  const { signUpInfo } = storeToRefs(signUpStore);

  const rows = ref([
    {
      id: 1,
      name: signUpInfo.value?.name,
      phone: signUpInfo.value?.phone,
      email: signUpInfo.value?.email,
      address: signUpInfo.value?.address,
      department: signUpInfo.value?.department.label,
    },
  ]);

  ...
</script>
profile
오늘도 뚠뚠 개미 개발자

0개의 댓글