20221017 [Spring Boot, Vue 연동]

Yeoonnii·2022년 10월 17일
0

TIL

목록 보기
48/52
post-thumbnail

통합구현

vue + Spring boot 연동하여 회원 관련
로그인, 회원가입, 암호변경, 회원정보변경, 회원탈퇴

Vue 개발환경 설정

  • 라우트
    CMD> npm i vue-router@next --save
  • 벡엔드 연동
    CMD> npm i axios --save
  • 상태관리
    CMD> npm i vuex --save
  • 서버구동
    CMD> npm run serve

라우터 사용하기

routes/index.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';

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;

main.js

라우터 사용 설정, 라우터 파일 위치 지정

import { createApp } from 'vue'
import App from './App.vue'

import routes from './routes/index';

const app = createApp(App);
app.use(routes);
app.mount('#app')

App.vue

라우트 사용하기

<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 사용시 값이 실시간 변경되는 것을 확인할 수 있다

JoinPage.vue

  • ...toRefs{state} 사용시 namev-model로 사용

  • const handleLogin 함수 사용시
    - async 사용한다 ⇒ 백엔드 주소 연동하기 때문

  • vue.config.js에 백엔드 주소 /ROOT 까지 연결 해 뒀기 때문에 /ROOT부터 주소를 작성해준다

  • 이미지 없으면 {"Content-Type":"application/json"}; 형태로 전송

  • 백엔드에서는 @RequestBody Member member로 받았다

  • 이전에 유효성 검사 실행했어야 한다! 지금은 생략
  • axios사용하여 post 형태로 보낸다 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>

아이디 중복확인

MemberRestController.java

@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;
    }

JoinPage.vue

구현 로직
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>

로그인

LoginPage.vue

<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>

0개의 댓글