[Vue3/Typescript] 가위 바위 보 게임 만들기 – 2. 플러그인 설치 및 세팅

일반적으로 vue에서 개발 환경을 구성할 때 axios, store, router 등을 필수로 구성을 합니다. 이번 글에서는 이러한 플러그인들을 설치는 방법들을 정리하고자 합니다. 특히 store가 기존에는 Vuex를 사용해서 구성하였는 Vue를 만든 Evan You가 pinia를 더 추천하기에 이 플러그인으로 구성하도록 하겠습니다.

1. 플러그인 설치

 npm i axios path pinia vue-router

위와 같은 명령어로 필요할 플러그인들을 설치합니다.

각 플러그인들을 간단히 소개하자면 아래와 같습니다.

axios: Promise 기반 http 클라이언트입니다. 주로 백단 api를 호출할 때 사용합니다.

path: 설정에서 파일 경로 관련돼서 필요합니다.

pina: vuex 대체제로 설치하였습니다. 변수들을 저장하여 프로젝트에 공용으로 사용할 때 사용합니다.

vue-router: 웹페이지간의 이동(라우팅)을 구현할 수 있는 라이브러리입니다.

2. Axios

src/plugins 폴더를 만들고 그 아래위와 같이 정의합니다.

● axios.ts

import axios, {
  AxiosError,
  InternalAxiosRequestConfig,
  AxiosResponse,
} from "axios";

// 요청 인터셉터
axios.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 요청 전에 작업을 수행합니다.
    // 예: 인증 토큰 추가, 요청 헤더 수정 등
    return config;
  },
  (error: AxiosError) => {
    // 요청 인터셉터에서 오류가 발생한 경우 처리합니다.
    return Promise.reject(error);
  }
);

// 응답 인터셉터
axios.interceptors.response.use(
  (response: AxiosResponse) => {
    // 응답 전에 작업을 수행합니다.
    // 예: 응답 데이터 가공, 에러 처리 등
    return response;
  },
  (error: AxiosError) => {
    // 응답 인터셉터에서 오류가 발생한 경우 처리합니다.
    return Promise.reject(error);
  }
);

// Vue 3 플러그인으로 등록합니다.
export default {
  install: (app: any) => {
    app.config.globalProperties.$axios = axios;
  },
};

 

● main.ts

import axiosPlugin from "~/plugins/axios";
const app = createApp(App);
app.use(axiosPlugin);
app.mount("#app");

main.ts에 위의 코드를 추가하여 axios를 적용합니다.

그리고 테스트를 위해서

https://jsonplaceholder.typicode.com/

위의 사이트를 이용하여 proxy 설정과 alias설정하는 법을 살펴보겠습니다.

● vite.config.ts

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { resolve } from "path";

// https://vitejs.dev/config/
export default defineConfig({
  base: process.env.ELECTRON == "true" ? "./" : "/vue3-rock-paper-scissors/",
  server: {
    port: 4000,
    proxy: {
      "/sample": {
        target: "https://jsonplaceholder.typicode.com",
        changeOrigin: true,
        secure: false,
        rewrite: (path) => path.replace(/^\/sample/, ""),
      },
    },
  },
  resolve: {
    alias: {
      "~/": `${resolve(__dirname, "./src")}/`,
      vue: "vue/dist/vue.esm-bundler.js",
    },
  },
  plugins: [vue()],
});

sample이라는 경로를 플레이스홀더 사이트로 연결해 주는 설정, ~/ 시작하는 경로를./src로 연결해 주는 설정을 추가하였습니다. 마지막으로 개발서버 포트를 4000으로 열리도록 하였습니다.

3. Router

src/router => index.ts, routes.ts 파일을 추가한다

●routes.ts

import { defineComponent } from "vue";

const NotFound = defineComponent({
  name: "NotFound",
  template: "<div>Not Found</div>",
});
const sample = defineComponent({
  name: "sample",
  template: "<div>this is sample</div>",
});

const routes = [
  { path: "/", redirect: "/main" },
  {
    path: "/main",
    name: "main",
    component: () => import("~/pages/main/Main.vue"),
  },
  {
    path: "/home",
    name: "home",
    component: () => import("~/pages/home/Home.vue"),
  },
  {
    path: "/sample",
    name: "sample",
    component: sample,
  },
  { path: "/:catchAll(.*)+", component: NotFound },
];

export default routes;

 

main은 가위바위보 게임 관련된 코드를 구현할 주소이다.

sample은 템플릿으로 생성될 코드를 저 위치에 위치하게 하였다. 이 챕터에서 설정한 내용들을 간단히 테스트하는 페이지로 사용할 것이다. 

●index.ts

import { createRouter, createWebHashHistory } from "vue-router";
import routes from "~/router/routes.ts";

export const router = createRouter({
  history: createWebHashHistory("/vue3-rock-paper-scissors/"), // createWebHistory("/vue3-rock-paper-scissors/"),
  linkActiveClass: "active",
  routes,
});

hashhistory로 설정한 이유는 이후에 깃허브에 해당 소스를 호스팅 할 때 새로고침시 404가 발생하는데 아파치 같은 경우는 index.html로 리다이렉트 시켜주면 되지만, 깃허브는 지원을 안 해준다고 한다. 해쉬모드를 적용하면 url에 #이 붙는다.

이렇게 하면 새로고침시 404 문제가 해결된다.

● main.ts

import { router } from "~/router"; 
app.use(router);

 

main에 위의 코드를 추가한다.

4. store

위와 같이 폴더와 파일을 생성한다.

● counter.ts

import { defineStore } from "pinia";

export const useCounterStore = defineStore("counter", {
  state: () => {
    return { count: 0 };
  },
  actions: {
    increment(value = 1) {
      this.count += value;
    },
  },
  getters: {
    doubleCount: (state) => {
      return state.count * 2;
    },
    doublePlusOne(): number {
      return this.doubleCount + 1;
    },
  }
});

 

● index.ts

import type { App } from 'vue'
import { createPinia } from 'pinia'
import {watch} from 'vue'

const store = createPinia()

if (sessionStorage.getItem('store')) {
  store.state.value = {
    ...JSON.parse(sessionStorage.getItem('store') ?? '{}')
  }
}
watch(()=>store.state.value,
  (state) => {
    sessionStorage.setItem('store', JSON.stringify(state))
  },
  { deep: true }
)

export function setupStore(app: App<Element>) {
  app.use(store)
}

export { store }

 

위의 코드를 보면 watch로 변동이 있을 때마다 세션스토리지에 저장하고 새로고침 할 때 불러와서  스토어에 저장하는 것으로 데이터를 유지하고 있다. 처음에는 pinia-plugin-persist라이브러리를 사용하여 적용하였는데 기능에는 문제가 없었지만 타입오류가 에디터에 계속 발생해서 제거하고 위와 같이 구성하였다.

● main.ts

import { setupStore } from "~/store"; 
setupStore(app);

 

Home.vue에서 axios, router, store를 테스트해 볼 수 있도록 코드를 추가했다. 이 부분은 소스를 참고해서 직접 테스트해 보면 될 것 같습니다. 


소스

https://github.com/junseongday/vue3-rock-paper-scissors

Leave A Reply

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다