0. main.js
import { createApp } from 'vue'
import App from './App.vue'
import routes from './routes/index';
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import stores from './stores/index';
const app = createApp(App);
app.use(routes);
app.use(ElementPlus);
app.use(stores)
app.mount('#app');
1. /store/index.js
- state는 공통적으로 사용할 상태변수를 정하는 곳
- getters는 상태변수를 외부 컴포넌트에서 가져가는 메소드
- mutations는 외부에서 store의 상태변수 state를 바꿀 수 있게 해주는 메소드
- actions는 나중에
import {createStore} from 'vuex';
export default createStore({
// 상태변수
state : {
logged : false,
},
// getter => App.vue에서 사용
// 바꾼거 가져가는 역할
getters : {
getLogged(state) {
return state.logged;
}
},
// mutations => LoginView.vue, LogoutView.vue에서 사용
// 바꾸는 역할
mutations : {
setLogged(state, value) {
state.logged = value;
}
}
// app, login, logout 모두가 공통변수 state.logged를 사용하는것
// actions
})
2. App.vue
- 로그인 상태로 변해도 화면상에는 즉각적으로 적용이 안됨
- onMounted는 최초 한번만 작동하는 원리기 때문에
- 로그인 상태로 바뀐것을 즉각적으로 알아채지 못함
- 그래서 store사용
- 하지만 store의 getters는 reactive에서 동작이 안됨
- 그래서 따로 변수를 정함 => logged
- computed로 store의 logged변수를 계속 확인함
: const logged = computed( () => store.getters.getLogged)
- onMounted에서는 세션스토리지의 토큰상태를 확인해서 참, 거짓을 직접 쓰고, 스토어에 넣고, 불러들여서 참 거짓 상태를 정함.
- 로그인, 로그아웃은 바꾸기만 함(참, 거짓)
<template>
<div>
<button @click="handleMenu('home')">Home</button>
<button @click="handleMenu('login')" v-if="logged === false">Login</button>
<button @click="handleMenu('logout')" v-if="logged === true">Logout</button>
<button @click="handleMenu('join')" v-if="!logged">Join</button>
<button @click="handleMenu('mypage')" v-if="logged">Mypage</button>
<hr>
<router-view></router-view>
</div>
</template>
<script>
import { useRouter } from 'vue-router'
import { computed, onMounted, reactive } from '@vue/runtime-core';
import { useStore } from 'vuex';
export default {
setup () {
const router = useRouter();
const store = useStore();
const logged = computed( () => store.getters.getLogged)
onMounted( () => {
if(sessionStorage.getItem("TOKEN") !== null) {
store.commit('setLogged', true);
}
else {
store.commit('setLogged', false);
}
})
const handleMenu = (menu) => {
console.log('App.vue/handleMenu(menu) ===> ',menu);
router.push(menu);
}
return {
state,
logged,
handleMenu
}
}
}
</script>
3. /component/LoginView.vue
- 로그인 상태 변경
- 로그인 하면 response.data.token에 토큰정보가 들어온다.
- 토큰정보를 "TOKEN" 이라는 이름으로 sessionStorage에 저장한다.
: sessionStorage.setItem("TOKEN", response.data.token)
- 알림창을 띄우고,
- store에 logged 상태를 true로 바꾼다.
: store.commit('setLogged', true);
- 홈으로 이동한다
const response = await axios.post(url, body, {headers});
console.log('handleLogin/response ===> ',response);
if (response.data.status === 200) {
sessionStorage.setItem("TOKEN", response.data.token)
alert('로그인 되었습니다.');
// 이시점에 로그인상태를 바꿈
store.commit('setLogged', true);
router.push('home');
}
LoginView.vue - 전체코드
<template>
<div class="style2">
<div class="style1">
<div style="display: inline-block;">
<h3>Login</h3>
<el-form
label-width="100px"
style="max-width: 360px">
<el-form-item label="아이디">
<el-input v-model="state.id"></el-input>
</el-form-item>
<el-form-item label="암호">
<el-input type="password" v-model="state.pw"></el-input>
</el-form-item>
<el-form-item label=" ">
<el-button @click="handleLogin" type="primary">로그인</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script>
import { reactive, ref } from '@vue/reactivity'
import axios from 'axios';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
export default {
setup () {
const router = useRouter();
const store = useStore();
const state = reactive({
id : '',
pw : ''
});
const id = ref(null);
const pw = ref(null);
const handleLogin = async() => {
if (state.id.length <= 0) {
alert('아이디를 입력하세요');
id.value.focus();
return false;
}
if (state.pw === '') {
alert('암호를 입력하세요');
pw.value.focus();
return false;
}
const url = `/member/login`;
const headers = {"Content-Type":"application/json"};
const body = {
id : state.id,
pw : state.pw
}
const response = await axios.post(url, body, {headers});
console.log('handleLogin/response ===> ',response);
if (response.data.status === 200) {
sessionStorage.setItem("TOKEN", response.data.token)
alert('로그인 되었습니다.');
store.commit('setLogged', true);
router.push('home');
}
}
return {
state,
id,
pw,
handleLogin
}
}
}
</script>
4. /component/LogoutView.vue
- 화면 필요없음
- sessionStorage의 TOKEN을 지운다.
- 알림창을 띄운 후,
- 로그인 상태 logged를 거짓으로 바꾼다.
- 홈으로 이동
<script>
import { onMounted } from '@vue/runtime-core';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
export default {
setup () {
const router = useRouter();
const store = useStore();
onMounted( () => {
sessionStorage.removeItem("TOKEN");
alert('로그아웃 되었습니다.');
store.commit('setLogged', false);
router.push('home');
})
return {}
}
}
</script>