publicPath 배포할때만 설정!
publicPath를 사용하지 않으면 127.0.0.1:9090 으로 주소 사용 가능하다
// publicPath:'/ROOT/vue'
로그인 되었을때 마이페이지 / 로그아웃 버튼 나오게 하기
뷰의 app 컴포넌트와 로그인 컴포넌트가 서로 연결되어야 함
routes/index.js
, stores/index.js
=> 임의로 만든 파일이니 main.js에 등록한다
import { createRouter, createWebHashHistory } from 'vue-router';
import Home from '@/components/HomePage.vue';
import Login from '@/components/LoginPage.vue';
import Join from '@/components/JoinPage.vue';
import Logout from '@/components/LogoutPage.vue';
import Mypage from '@/components/MypagePage.vue';
const router = createRouter({
history : createWebHashHistory(), //주소 표시방법
routes : [
// 주소와 컴포넌트 매칭
{path : '/', name:'Home', component : Home},
{path : '/login', name:'Login', component : Login},
{path : '/join', name:'Join', component : Join},
{path : '/mypage', name:'Mypage', component : Mypage},
{path : '/logout', name:'Logout', component : Logout},
]
});
export default router;
import { createStore } from "vuex";
export default createStore({
state() { //공통변수 생성 => 변수 정의 + if문, 반복문등 추가 연산작업 가능한 형태
let tmp = false;
if(sessionStorage.getItem("token") !== null){
tmp = true;
}
return {
logged : tmp,
counter : 1,
}
},
// state : { //공통변수 생성 => 이 형태는 변수만 정의할 수 있음! if문이나 추가 연산작업 불가
// logged : false,
// counter : 1
// },
getters : { //App.vue에서 값을 가져감
getLogged : state => {
return state.logged;
},
getCounter : state => {
return state.counter;
}
},
mutations : { // 변경되는 부분 (LoginPage.vue, LogoutPage.vue)
setLogged(state, value){ //value 값이 와야한다
state.logged = value;
},
setCounter(state){ // 값이 없어도 1씩 증가
state.counter++;
}
},
actions : { // 동기화 되는 부분 (백엔드 연동 시간이 필요한 작업들)
// 토큰을 이용하여 토큰이 유효한지 확인
}
})
<template>
<div>
<h3>고정되는 메뉴</h3>
<router-link to="/"><button>홈</button></router-link>
<router-link to="/login" v-if="!state.logged"><button>로그인</button></router-link>
<router-link to="/join" v-if="!state.logged"><button>회원가입</button></router-link>
<router-link to="/logout" v-if="state.logged"><button>로그아웃</button></router-link>
<router-link to="/mypage" v-if="state.logged"><button>마이페이지</button></router-link>
<hr />
{{state}}
<router-view></router-view>
</div>
</template>
<script>
import { reactive } from '@vue/reactivity'
import { useStore } from 'vuex'
import { computed } from '@vue/runtime-core';
export default {
setup () {
const store = useStore();
const state = reactive({
logged : computed(() => store.getters.getLogged),
counter : computed(() => store.getters.getCounter),
name : '임시'
});
return {state}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: left;
color: #2c3e50;
margin-top: 60px;
}
</style>
<template>
<div>
<h3>로그아웃</h3>
</div>
</template>
<script>
import { onMounted } from '@vue/runtime-core'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router';
export default {
setup () {
const store = useStore();
const router = useRouter();
onMounted(() => {
if(confirm('로그아웃할까요?')){
sessionStorage.removeItem("token");
store.commit('setLogged', false);
}
router.push({path:'/'});
});
return {}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<h3>마이페이지</h3>
<button @click="menu = 1">정보수정</button>
<button @click="menu = 2">회원탈퇴</button>
<menu-1 v-if="menu ===1" title="정보수정111" @sendData="sendData1"></menu-1>
<menu-2 v-if="menu ===2" title="정보수정111" ></menu-2>
</div>
</template>
<script>
import { reactive, toRefs } from '@vue/reactivity';
import Menu1 from "./comp/Menu1Page.vue";
import Menu2 from "./comp/Menu2Page.vue";
export default {
// Menu1Page, Menu2Page컴포넌트 설정
components :{
Menu1,
Menu2,
},
setup () {
const state = reactive({
menu : 1
});
// Menu1page의 전송버튼을 눌렀을때 호출되는 부모메소드
const sendData1 = (val) => {
console.log(val);
}
return {...toRefs(state), sendData1}
}
}
</script>
<style lang="scss" scoped>
</style>
props ⇒ 마이페이지에서 Menu1Page, Menu2Page로
뷰 props 사용 방법
=> Menu1Page, Menu2Page컴포넌트 설정
export default {
components :{
Menu1,
Menu2,
},
<template>
<div>
<h3>{{ title }}</h3>
나이 : <input type="text" v-model="age"/>
연락처 : <input type="text" v-model="phone"/>
<!-- <button @click="handleEmit">전송</button> -->
<button @click="handleUpdate">정보수정</button>
</div>
</template>
<script>
import { reactive, toRefs } from '@vue/reactivity'
import axios from 'axios';
import { onMounted } from 'vue';
export default {
props:{
title : String
},
// setup (props, {emit}) {
setup (props, ) {
const state = reactive({
title : props.title, //부모에서 받아오는 값
age : 0,
phone : '',
token : sessionStorage.getItem("token") //token을 받아와서 저장
});
const handleData = async() => {
const url = `ROOT/api/member/selectone.json`;
const headers = {
"Content-Type" :"application/json",
"TOKEN" : state.token //jwtfilter에서 TOKEN이라고 이름을 지정해줬다
};
const { data } = await axios.get(url, {headers});
console.log(data)
if(data.status === 200){
state.age = data.result.age;
state.phone = data.result.phone;
}
}
const handleUpdate = async() => {
const url = `ROOT/api/member/update.json`;
const headers = {
"Content-Type" :"application/json",
"TOKEN" : state.token //jwtfilter에서 TOKEN이라고 이름을 지정해줬다
};
const body = {
age : state.age,
phone : state.phone
}
const { data } = await axios.put(url, body, {headers});
console.log(data)
// if(data.status === 200)
}
// const handleEmit = () => {
// // 부모쪽으로 이벤트 발생
// emit('sendData', {key : 'a', value : 'b'});
// }
onMounted(()=> {
handleData();
})
return {...toRefs(state), handleUpdate}
}
}
</script>
<style lang="scss" scoped>
</style>