๐ ์๋ฒ๋ฅผ ํตํด api ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋๋ฐ ์๊ฐ์ด๊ฑธ๋ฆฌ๋๊ฒ์ ๋ํด loading์ฐฝ์ ๋์ฐ๊ธฐ
const loading = ref(false) // api๋ฅผ ๊ฐ์ ธ์ฌ๋ ๋ก๋ฉ๋ชจ๋ฌ
๐ loading ๋ณ์๋ฅผ ๋ฐ์ํ์ผ๋ก ๋ง๋ ๋ค
const todoList = ref([]) // ์ธ์ ์ฌ์ง ๋ชจ๋ฅด๋๊น ref๋ก ๋ง๋ ๋ค
loading.value = true // api๋ฅผ ๊ฐ์ ธ์ค๋ ๋ก๋ฉ์์
์ด ์์๋๋ฉด
const loadPageData = async(page) =>{// api์์ ๋ฐ์ res.data์ค์์ content๋ผ๋ ์์ฑ์ todoList.value์ ์ง์ด๋ฃ๋๋ค.
const data = await getList(page)
todoList.value = data.content //data์ content์์ฑ์ ๊ฐ์ ธ์จ๋ค.
loading.value = false // ๋ก๋ฉ์์
์ด ๋๋๋ฉด
}
๐ api์๋ฒ ํต์ ํ๋ ์ฝ๋ ๋ด๋ถ์์ loading.value๊ฐ์ true -> false๋ก ๋ณ๊ฒฝํด์ค๋ค.
<div v-if="loading" class="loadingDiv">
<h1>loading.......</h1>
</div>
๐ loading์ด true์ผ๋๋ loading์ด๋ผ๋ ํ๋ฉด์ด ์ ๊น ์ถ๋ ฅ๋๋ค.
๐ ์ํ๊ด๋ฆฌ๋ฅผ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
๐ npm install pinia
๐ Pinia์ store์ ์ ์ฅํ์ฌ ์ฌ์ฉํ์๋ ์ด์ ์ ์ด๋ค ์ปดํฌ๋ํธ๊ฐ์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ ์ฝ์์ด ์ด์ฉํ ์ ์๋ค๋๊ฒ์ด๋ค.

import { defineStore } from "pinia";
import { ref } from "vue";
const useMember = defineStore('memberStore', ()=>{ //memberStore๋ ์คํ ์ด์ ๊ณ ์ ID
const member = ref({mid:null}) // ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ๊ฐ์ ๋ฐ์ํ์ผ๋ก ์ ์ฅ
const login = (valueId) => {
console.log('login..... '+valueId)
member.value.mid = valueId // pinia store์ ์ํ๋ฅผ ์
๋ฐ์ดํธ
localStorage.setItem('mid',valueId) // ๋ก์ปฌ์คํ ๋ฆฌ์ง์ ์ํ๋ฅผ ์
๋ฐ์ดํธ
}
const logout = () => {
console.log('logout.........')
member.value.mid = null
localStorage.removeItem('mid')
}
return{member,login, logout} // ํด๋น return๊ฐ์ ํตํด ๋์ค์ useMember๋ฅผ ํธ์ถํ๊ณ ,(member,login, logout) ์ํ๋ ๋ณ์ ๋ฐ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
})
export default useMember
๐ pania๋ฅผ ์ด์ฉํ์ฌ useMember๋ผ๋ store๋ฅผ ๋ง๋ค๊ณ , member๋ผ๋ ๋ฐ์ํ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ก๊ทธ์ธ์ ํ๋์ง ์์์๋๋ก ๋ง๋ ๋ค.
๐ login ๋ฉ์๋์์๋ loginPage.vue์์ input์ ํตํด midInput์ด๋ผ๋ ๊ฐ์ ๋ฃ๊ณ , ๊ทธ ๋ณ์๊ฐ์ ๋งค๊ฐ๋ณ์๋ก ๋ค์ด์ค๊ฒ ๋๋ค.
๐ localStoralge๋ฅผ ํตํด ๋ก๊ทธ์ธํ ๊ธฐ๋ก์ ๋จ๊ธฐ๊ฒ๋์ด ์๋ก๊ณ ์นจ์ ํ๋๋ผ๋ ๋ก๊ทธ์ธ๊ธฐ๋ก์ด ๋จ์์์ด ์ฌ๋ก๊ทธ์ธ์ ํ ๋ฒ๊ฑฐ๋ก์์ ์ค์ธ๋ค.
๐ useMember์ return๊ฐ์ useMember๋ฅผ ํธ์ถํ์ฌ ์ํ๋ ๋ฉ์๋ ๋ฐ ๋ณ์๋ฅผ ์ด๋ ์ปดํฌ๋ํธ์์๋ ์ฌ์ฉํ ์ ์๋ค. (ํ์ง๋ง import๋ ํ์)
<template>
<div>
<h1>Login Page</h1>
<input type="text" v-model="midInput">
<button @click="handleClick">Login</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import useMember from '../stores/useMember';
const {login} = useMember() // useMember.js์ login ๊ธฐ๋ฅ ์ฌ์ฉ
const midInput = ref('') // input๋๋ id๊ฐ๊ณผ ์ฐ๋๋๋๋ก v-model์๋ฐฉํฅ์ ์ฌ์ฉ
const handleClick = () => {
const mid = midInput.value // input text ๋ก ์
๋ ฅํ id ๊ฐ์ mid๋ณ์์ ๋ฃ๊ณ
login(mid) // store์ ์ ์ฅ๋ login๋ฉ์๋์ mid ์ธ์๋ฅผ ๋ฃ์ด ํธ์ถฃ
}
</script>
<style lang="scss" scoped>
</style>
๐ useMember store๋ฅผ importํ์ฌ ์ฌ์ฉํ๋๋ชจ์ต
import useMember from '../stores/useMember'
const IndexPage = () => import('../pages/todo/IndexPage.vue')
const TodoListPage = () => import('../pages/todo/TodoListPage.vue')
const TodoAddPage = () => import('../pages/todo/TodoAddPage.vue')
const TodoReadPage = () => import('../pages/todo/TodoReadPage.vue')
const moveToLogin = (to, from, next) => { // ์ด๋ฐ์์ผ๋ก login์ ํ๊ณ ๋ค๋ฅธ ํ์ด์ง๋ก ๋์ด๊ฐ์์๋ ๋ฉ์๋๋ฅผ ๋นผ๋์ผ๋ฉด ๋ค๋ฅธ ํ์ด์ง๋ก ๊ฐ๋ ๋ก๊ทธ์ธ์ ํ ์ฌ๋๋ง ํ ์์๋๋ก filter๊ธฐ๋ฅ์ ํ ์ ์๋ค.
const checkLogin = () => { // checkLogin ๋ฉ์๋๋ ๋ก๊ทธ์ธ ํ ๊ธฐ๋ก์ด ์๋ค๋ฉด true / ์๋๋ฉด false
const {member} = useMember() // useMember.js์์ member๋ผ๋ ๋ฐ์ํ ๋ณ์๋ฅผ ์ฌ์ฉํจ
return member.mid ? true : false
}
console.log('move to add page '+ checkLogin())
if(checkLogin()){
next() // ๋ก๊ทธ์ธ ๊ธฐ๋ก์ด ์์ผ๋ฉด ๋ค๋ฅธ ์๋น์ค๋ฅผ ์ด์ฉํ ์ ์๋ค.
}else{
next('/login') // ๋ก๊ทธ์ธ ๊ธฐ๋ก์ด ์์ผ๋ฉด login ํ์ด์ง๋ก ๋์ด๊ฐ๋ค.
}
}
const todoRouting = {path: "/todo",
component: IndexPage, // Index๊ฐ ๊ฐ์ฅ์์์๊ณ , ๊ทธ ์๋์ todo list / todoadd๊ฐ ์๋๊ฒ์ด๋ค.
children: [
{path: "list", component: TodoListPage, beforeEnter: moveToLogin}, // ์ค์ ๋ก๋ path: /todo/list, component๋ ์์ const TodoListPage๋ก ์ธํด์ import์ฐ๊ฒฐ์ด ๋์ด์๋๊ฒ.
{path: "add", component: TodoAddPage, beforeEnter: moveToLogin},
{path: "", redirect: '/todo/list'}, // ์ด๊ฒ๋๋ฌธ์ Indexpage์ ๊ฐ์ฅ ๊ธฐ์ดํ์ด์ง๊ฐ listํ์ด์ง๊ฐ ๋๋๊ฒ.
{path: "read/:mno", component: TodoReadPage, beforeEnter: moveToLogin},
]
}
export default todoRouting //๋ค๋ฅธํ์ผ์์ todoRouting์ ์ฝ๊ฒ import
<script setup>
import { RouterLink, RouterView } from 'vue-router';
import useMember from './stores/useMember';
const {member, logout} = useMember() //useMember.js ์์ member๋ณ์์ logout๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ฒ ๋ค.
</script>
<template>
<div>
<span><RouterLink to="/">Main</RouterLink></span> <!--Aํ๊ทธ ์ฒ๋ผ ์๊ธด ํ๋ฉด์ด๋-->
<span><RouterLink to="/about">About</RouterLink></span>
<span><RouterLink to="/todo">Todo</RouterLink></span>
<span v-if="member.mid === null"><RouterLink to="/login">Login</RouterLink></span> <!--์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ํ ๊ธฐ๋ก์ด ์์๋ ๋ก๊ทธ์ธ ๋ฒํผ์ด ๋ณด์-->
<span v-if="member.mid !== null"><button @click="logout">Logout</button></span> <!--์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ํ ๊ธฐ๋ก์ด ์์๋ ๋ก๊ทธ์์ ๋ฒํผ์ด ๋ณด์-->
</div>
<div>
<hr/>
MemberID : {{ member.mid }}
<hr/>
</div>
<RouterView></RouterView> <!--๋ผ์ฐํฐ๋ก ์ด์ฉ๋ ํ์ด์ง๋ฅผ ์ถ๋ ฅ-->
</template>
<style scoped>
span{
margin-left: 1em;
}
</style>
import { createApp } from 'vue'
import App from './App.vue'
import routeConfig from './routers'
import { createPinia } from 'pinia'
createApp(App).
use(routeConfig).
use(createPinia()). // pinia์ฌ์ฉํ๋ ค๋ฉด ํ์
mount('#app') // use(routeConfig)์ผ๋ก ์ค์ ํ ๋ผ์ฐํฐ๋ก ์ฌ์ฉํ๊ฒ ๋ค