vue + Spring boot 연동하여 회원 관련
로그인, 회원가입, 암호변경, 회원정보변경, 회원탈퇴
- 라우트
CMD> npm i vue-router@next --save- 벡엔드 연동
CMD> npm i axios --save- 상태관리
CMD> npm i vuex --save- 서버구동
CMD> npm run serve
라우터로 사용할 컴포넌트를 매칭해준다
import { createRouter, createWebHashHistory } from 'vue-router';
import Home from '@/components/HomePage.vue';
import Login from '@/components/LoginPage.vue';
import Join from '@/components/JoinPage.vue';
const router = createRouter({
history : createWebHashHistory(), //# ,주소 표시방법
routes : [
// 주소와 컴포넌트 매칭
{path : '/', name:'Home', component : Home},
{path : '/login', name:'Login', component : Login},
{path : '/join', name:'Join', component : Join},
]
});
export default router;
라우터 사용 설정, 라우터 파일 위치 지정
import { createApp } from 'vue'
import App from './App.vue'
import routes from './routes/index';
const app = createApp(App);
app.use(routes);
app.mount('#app')
라우트 사용하기
<template>
<div>
<h3>고정되는 메뉴</h3>
<router-link to="/"><button>홈</button></router-link>
<router-link to="/login"><button>로그인</button></router-link>
<router-link to="/join"><button>회원가입</button></router-link>
<hr />
<router-view></router-view>
</div>
</template>
<script>
export default {
}
</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>
결과화면
{{state}}
찍어서 변경되는 값을 확인하며 진행하기
reactive
사용시 값이 실시간 변경되는 것을 확인할 수 있다
...toRefs{state}
사용시 name
⇒ v-model
로 사용
const handleLogin 함수 사용시
- async 사용한다 ⇒ 백엔드 주소 연동하기 때문
vue.config.js에 백엔드 주소 /ROOT 까지 연결 해 뒀기 때문에 /ROOT부터 주소를 작성해준다
이미지 없으면 {"Content-Type":"application/json"};
형태로 전송
백엔드에서는 @RequestBody Member member
로 받았다
const { data } = await axios.post(url, body, {headers});
<template>
<div>
<h3>회원가입 페이지</h3>
아이디 : <input type="text" name="userid" /><label>중복확인</label><br />
암호 : <input type="text" name="userpw" /><br />
암호확인 : <input type="text" name="userpw1" /><br />
나이 : <input type="text" name="age" /><br />
성별 :
<select name="gender">
<option value="M">M</option>
<option value="F">F</option>
</select><br />
연락처 : <input type="text" name="phone" /><br />
권한 : <input type="text" name="role" value="CUSTOMER"/><br />
<hr />
<button>회원가입</button>
</div>
</template>
<script>
export default {
setup () {
const router = useRouter();
const state = reactive({
userid:'',
userpw:'',
userpw1:'',
age:0,
gender:'M',
phone:'',
role:'CUSTOMER',
});
const handleJoin = async() => {
console.log('회원가입버튼이 클릭됨')
// 유효성 검사 실행
const url = `/ROOT/api/member/join.json`;
// 이미지 없으면 무조건 {"Content-Type":"application/json"};
// 백엔드에서는 @RequestBody Member member로 받았다
const headers = {"Content-Type":"application/json"};
const body = {
userid : state.userid,
userpw : state.userpw,
age : state.age,
gender : state.gender,
phone : state.phone,
role : state.role,
}
const { data } = await axios.post(url, body, {headers});
console.log(data);
if(data.status === 200){
alert('회원가입완료');
router.push({path:'/'});
}
}
return {
state, ...toRefs(state), handleJoin
};
}
}
</script>
<style lang="scss" scoped>
</style>
⇒ @RequestParam(name = "userid") String userid1
으로 받아야 프론트에서 주소에 아이디를 넘겨줄 수 있다
// 아이디 중복확인
@GetMapping(value = "/idcheck.json")
public Map<String, Object> idcheckGET(@RequestParam(name = "userid") String userid){
System.out.println(userid);
Map<String, Object> map = new HashMap<>();
try {
boolean ret = memberRepository.existsById(userid);
map.put("status", 200);
map.put("result", ret); //있으면 참, 없으면 거짓
} catch (Exception e) {
map.put("status", -1);
map.put("result", e.getMessage());
}
return map;
}
구현 로직
1. input 태그에@keyup
사용하여 아이디 입력시 마다 중복확인 진행
⇒아이디 : <input type="text" v-model="userid" @keyup="handIDcheck" />
2. label 태그 안에{{idcheck}}
값을 넣어준다
<label>중복확인</label>
⇒<label>{{idcheck}}</label>
3.const handIDcheck
생성
⇒ 결과값(true/false)에 따라state.idcheck
의 값을 변경해준다
<template>
<div>
<!-- {{state}} -->
<h3>회원가입 페이지</h3>
아이디 : <input type="text" v-model="userid" @keyup="handIDcheck" /><label>{{idcheck}}</label><br />
암호 : <input type="text" v-model="userpw" /><br />
암호확인 : <input type="text" v-model="userpw1" /><br />
나이 : <input type="text" v-model="age" /><br />
성별 :
<select v-model="gender">
<option value="M">M</option>
<option value="F">F</option>
</select><br />
연락처 : <input type="text" v-model="phone" /><br />
권한 : <input type="text" name="role" value="CUSTOMER"/><br />
<hr />
<button @click="handleJoin">회원가입</button>
</div>
</template>
<script>
import axios from 'axios';
import { reactive, toRefs } from '@vue/reactivity'
import { useRouter } from 'vue-router';
export default {
setup () {
const router = useRouter();
const state = reactive({
userid:'',
userpw:'',
userpw1:'',
age:0,
gender:'M',
phone:'',
role:'CUSTOMER',
idcheck : '중복확인'
});
const handleJoin = async() => {
console.log('회원가입버튼이 클릭됨')
// 유효성 검사 실행
const url = `/ROOT/api/member/join.json`;
// 이미지 없으면 무조건 {"Content-Type":"application/json"};
// 백엔드에서는 @RequestBody Member member로 받았다
const headers = {"Content-Type":"application/json"};
const body = {
userid : state.userid,
userpw : state.userpw,
age : state.age,
gender : state.gender,
phone : state.phone,
role : state.role,
}
const { data } = await axios.post(url, body, {headers});
console.log(data);
if(data.status === 200){
alert('회원가입완료');
router.push({path:'/'});
}
}
const handIDcheck = async() => {
if(state.userid.length > 0){ //아이디의 길이가 0보다 큰 경우
const url = `/ROOT/api/member/idcheck.json?userid=${state.userid}`;
const headers = {"Content-Type":"application/json"};
const { data } = await axios.get(url,{headers});
console.log(data);
if(data.status === 200) {
if(data.result === true){
state.idcheck = '사용불가';
}
else {
state.idcheck = '사용가능';
}
}
}
}
return {
state, ...toRefs(state), handleJoin, handIDcheck
};
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<div>
<h3>로그인</h3>
<input type="text" v-model="userid" />
<input type="password" v-model="userpw" />
<button @click="handleLogin">로그인</button>
</div>
</template>
<script>
import { reactive, toRefs } from '@vue/reactivity'
import axios from 'axios';
import { useRouter } from 'vue-router';
export default {
setup () {
const router = useRouter();
const state = reactive({
userid:'',
userpw:'',
});
const handleLogin = async() => {
const url = `/ROOT/api/member/login.json`;
const headers = {"Content-Type":"application/json"};
const body = {
userid : state.userid,
userpw : state.userpw,
role : 'CUSTOMER'
}
const {data} = await axios.post(url, body, {headers});
console.log(data);
if(data.status == 200){
sessionStorage.setItem("token", data.result);
router.push({path:'/'});
}
};
return {
state,
...toRefs(state),
handleLogin
}
}
}
</script>
<style lang="scss" scoped>
</style>