본문 바로가기
▶ Front-End/Vue.js

Vue3 기초 예제 - 로그인(pinia)

by 오늘도 코딩 2023. 10. 30.
728x90
반응형

Pinia 간단한 설명과 로그인 기초 예제

*자세한 설명 생략

 

 

▷ Pinia 란?

*Store 관련 자세한 설명 아래 링크 참고

 

    - 모든 컴포넌트들에 대한 데이터 저장소 역할 및 관리하는 Store

 

    - Vuex 보다 더 간단하고, Composition API 스타일을 제공

 

 

▷ Pinia 설치

*vue-cli를 통해 Project 생성 후 설치

 

💡npm install pinia

 

 

▷ 기초 예제 - 로그인

 

- main.js

*pinia 모듈 등록

import { createApp } from 'vue'
import App from './App.vue'
import { router } from '@/router/MenuNav.js'
import Axios from "axios";
import { createPinia } from 'pinia'

createApp(App)
    /** 모듈 사용 등록 */
    .use(router)
    .use(createPinia())

    /** 전역 설정 */
    // Axios
    .provide('$Axios', Axios)
    // API_URI
    .provide('$BHS_CMM_LGN', "http://IP:Port/bhs/cmm/login.do")

    /** 연결 */
    .mount('#app')

 

- LoginStore.js

import { defineStore } from 'pinia'
import { ref } from 'vue'
import { router } from '@/router/MenuNav.js'

export const useLoginStore = defineStore(
    "LoginStore",
    () => {
        /** 인증토큰 */
        const JWT = ref(null)

        /** SET */
        function setUser(jwt) { JWT.value = jwt }

        /** 로그인 체크 */
        function checkUser() {
            if (JWT.value == null) {
                router.push({ path: "/" })
                alert("로그인 후 이용해주세요.")
            }
        }

        return { JWT, setUser, checkUser }
    }
)

 

- LoginTestCmp.vue

<template>
    <div class="APICallTestCmp">
        <h1>🏠 HOME</h1><br /><br />
        <div class="login">
            <h2>Login</h2>
            <input v-model="id" placeholder="아이디">
            <input v-model="pwd" placeholder="패스워드">
            <button @click="call(id, pwd);">Login</button>
        </div><br />
        <div>
            <h4>JWTStore : </h4>
            <div style="width: 700px; height: 150px; overflow: auto;">
                {{ useLoginStore().JWT }}
            </div>
        </div>
        <div>
            <h4>API Response : </h4>
            <div style="width: 700px; height: 150px; overflow: auto;">
                {{ resJWT }}
            </div>
        </div>
    </div>
</template>

<script setup>
import { inject, ref } from 'vue'
import { router } from '@/router/MenuNav.js'
import { useLoginStore } from '@/store/LoginStore.js'

const id = ref("")
const pwd = ref("")
const Axios = inject("$Axios")
const API_URI = inject("$BHS_CMM_LGN")
const resJWT = ref("")

function call(id, pwd) {

    const REQ_DATA = {
        "id": id,
        "pwd": pwd
    }

    Axios
        .post(API_URI, REQ_DATA)
        .then((res) => {

            const resVO = res.data

            if (resVO.resultCode == "0000") {
                resJWT.value = resVO.jwt

                useLoginStore().setUser(resVO.jwt)

                router.push({ path: "/" })

                alert("로그인 완료")
            } else {
                alert(resVO.resultMsg)
            }
        })
        .catch(() => {
            console.log("실패");
        })
}
</script>

 

- CompositionTestCmp.vue

*로그인 체크 로직 추가

*Composition API

<template>
    <div class="CompositionTestCmp">
        <h1>👨‍🏫 Composition Example</h1><br /><br />
        <button @click="initTest();">초기화</button>
        <div>
            <h4> 입력 :
                <input v-model="inData" @keyup.enter="addList(inData);" placeholder="아무거나 입력해주세요.">
            </h4>
        </div>
        <div>
            <h4> 선택 :
                <select v-model="select">
                    <option value="-" selected>선택해주세요.</option>
                    <option v-for="(item, i) in list" :key="i" :value="item">{{ item }}</option>
                </select>
            </h4>
        </div>
        <div>
            <h4> 확인 :
                {{ select }}
            </h4>
        </div>
        <div>
            <h4> 리스트 현황</h4>
            <div v-for="(item, i) in list" :key="item">
                {{ i }} → {{ item }}
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { useLoginStore } from '@/store/LoginStore.js'

/** 반응형 객체 */
let inData  = ref("");
let list    = ref([]);
let select  = ref("-");

/** 로그인 체크 */
onMounted(() => { useLoginStore().checkUser() })

/** 리스트 값 추가 */
function addList(data) {
    if (data == "" || data == null) {
        alert("입력 값이 없습니다.");
    } else {
        list.value.push(data);
        inData.value = "";
    }
}

/** 초기화 */
function initTest() {
    inData.value = "";
    list.value = [];
    select = "-";
}
</script>

 

- ForTestCmp.vue

*Test Composition 모두 로그인 체크 로직 추가

*Options API

<template>
    <div class="ForTestCmp">
        <h1>👨‍🏫 For Test </h1><br />
        <h4>리스트</h4>
        <div>{{ list }}</div>
        <h4>리스트 값</h4>
        <div v-for="(obj, i) in list" :key="obj">
            {{ i }} → {{ obj }}
        </div>
    </div>
</template>

<script>
import { useLoginStore } from '@/store/LoginStore.js'

export default {
    data: () => {
        return {
            list:
                [
                    { id: '001', message: 'Hello For' },
                    { id: '002', message: 'Hello Test' },
                    { id: '003', message: 'Hello World' }
                ]
        }
    },
    /** 로그인 체크 */
    mounted() { useLoginStore().checkUser() }
}
</script>

 

 

▷ 결과 확인

 

① TEST 메뉴 접근, 로그인 체크 확인

 

② 로그인 완료 확인

 

③ API Server에서 받아온 JWT 확인

 

④ 로그인 후, TEST 메뉴 정상 접근 확인

 

⑤ 새로 고침 시 로그인 체크 후 다시 로그인 화면으로 이동

 

 

▷ 참고

 

[Store]Vuex vs Pinia, Vue 스토어 비교

안녕하세요. 오늘은 오랜만에 Vue 관련한 글을 써보려고 합니다. 원래 예전부터 쓰려고 했던 주제인데, 클라우드 자격증을 준비하면서 클라우드 쪽 포스팅에 집중을 하다 보니 포스팅이 예정보

codeup-eugene.tistory.com

 

Vue 3의 공식 Store | Vue.js를 위한 직관적인 스토어

직관적이고 타입 안전한 가벼운 그리고 유연한 Vue 스토어

pinia.vuejs.kr

 

 

▷ 관련 글

 

Vue3 기초 예제 프로젝트 정리

Vue3 기초 예제 프로젝트 구조 및 소스 중간 정리 *관련 글이 점점 늘어나 하나로 통합하기 위함 *이 글에서 만 싱크 맞춤 *주석 이외 설명 생략 *자세한 설명 생략 ▷ 프로젝트 전체 구조 < 파일 따

coding-today.tistory.com

 

 

728x90
728x90

댓글