home.ejs
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>home</title>
</head>
<body>
<div id="app">
<router-link to="/vue/home1">홈</router-link>
<router-link to="/vue/login1">로그인</router-link>
<router-link to="/vue/join1">회원가입</router-link>
<router-link to="/vue/board1">게시판</router-link>
<hr>
<router-view></router-view>
</div>
<!-- npm install vue --save -->
<!-- npm install vue-router --save -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@3.5.1/dist/vue-router.js"></script>
<script src="/javascripts/applogin.js"></script>
<script src="/javascripts/appjoin.js"></script>
<script src="/javascripts/apphome.js"></script>
<script src="/javascripts/appnotfound.js"></script>
<script src="/javascripts/appboard.js"></script>
<script src="/javascripts/appboardwrite.js"></script>
<script src="/javascripts/appboardcontent.js"></script>
<script>
var appRoute = new VueRouter({
//mode: 'history',
routes: [
{ path: "/", redirect: "/vue/home1"},
{ path: "*", component: appNotFound},
{ path: "/vue/home1", component: appHome, name: "home1"},
{ path: "/vue/login1", component: appLogin, name: "login1" },
{ path: "/vue/join1", component: appJoin, name:"join1" },
{ path: "/vue/board1", component: appBoard, name:"board1" },
{ path: "/vue/boardcontent1", component: appBoardContent, name:"boardcontent1" },
{ path: "/vue/boardwrite1", component: appBoardWrite, name:"boardwrite1"}
]
});
new Vue({
el: '#app',
router: appRoute
});
</script>
</body>
</html>
<router-link to="url경로">글자</router-link> => router-link태그를 사용할 경우, HTML의 a태그와 같이 적용되어 클릭할 경우 지정한 url경로로 이동해준다.
<router-view></router-view> => <script>태그로 불러들여진 js파일이 실질적으로 화면으로 나타난다.
routes: [{...}] => 이 부분은 경로, 컴포넌트, 이름을 지정해 주는 곳으로 컴포넌트를 지정할 때 해당 js파일 내 정의 된 컴포넌트의 이름과 일치해야한다.
apphome.js
var appHome = {
template: `
<div>
<h3>home page</h3>
</div>
`
};
appHome에 정의되어 있는 template는 HTML태그로 구성되어 있는 것으로 실제 home.ejs파일의 <router-view>태그 내부로 들어가 화면에 출력하게 된다.
applogin.js
var appLogin = {
template: `
<div>
<fieldset style="width: 300px; padding: 20px;">
<legend>로그인</legend>
<div>
<label style="display: inline-block; width: 70px;">아이디</label>
<input type="text" v-model="userid" ref="userid">
</div>
<div>
<label style="display: inline-block; width: 70px;">비밀번호</label>
<input type="password" v-model="userpw" ref="userpw">
</div>
<hr>
<input type="button" value="로그인" v-on:click="checkLogin()">
</fieldset>
</div>
`,
data: function () {
return {
userid: '',
userpw: ''
}
},
methods: {
checkLogin() {
if (this.userid === '') {
alert('아이디를 입력해주세요.');
this.$refs.userid.focus();
return;
}else if(this.userpw === ''){
alert('패스워드를 입력해주세요.');
this.$refs.userpw.focus();
return;
}
const sendData = {
userid: this.userid,
userpw: this.userpw
};
const result = {
ret: 1
}
if(result.ret === 1){
alert('로그인 성공하였습니다.');
this.$router.push({path:'/vue/home1'});
}
}
}
};
applogin파일은 로그인을 하기위해 유효성검사와 로그인 성공 시 홈 화면으로 이동시켜주는 기능을 가지고 있다.
사용자로부터 아이디와 패스워드 값을 반기 위하여 v-model을 사용한다. - v-model은 사용자가 입력칸에 키보드로 입력을 할 때 실시간으로 변경사항을 해당 변수에 저장한다. - 해당 변수는 data내부에 정의되어 있어야한다. 현재 userid와 userpw는 공백으로 이루어져있다. 그 이유는 입력받은 값이 존재하지 않기 때문이다.
v-on:과 관련된 이벤트의 종류는 많지만 그 중 클릭 이벤트를 사용하기 위해서는 v-on:click="메서드명"을 사용하여야 한다. 해당 메서드는 methos내부에 정의되어 있어야 한다.
유효성을 검증하기 위해 methods 내부에 checkLogin메서드를 정의한다. userid와 userpw가 공백일 경우 return을 수행하여 더 이상 진행이 되지 않도록 설정하였다. 유효성 검증이 완료되면 sendData객체에 userid와 userpw를 담아 서버로 전송한다.
appjoin.ejs
var appJoin = {
template: `
<div>
<fieldset style="width:450px; padding:20px">
<legend>회원가입</legend>
<div>
<label style="display:inline-block; width:110px">아이디</label>
<input type="text" v-model="user_id">
</div>
<div>
<label style="display:inline-block; width:110px">비밀번호</label>
<input type="password" v-model="user_pw">
</div>
<div>
<label style="display:inline-block; width:110px">비밀번호 확인</label>
<input type="password" v-model="user_pw_check">
<input type="button" value="비밀번호 확인" v-on:click="checkPw()">
</div>
<div>
<label style="display:inline-block; width:110px">이름</label>
<input type="text" v-model="user_name">
</div>
<div>
<label style="display:inline-block; width:110px">이메일</label>
<input style="width: 55px;" type="text" v-model="user_email">@
<select v-model="user_email2">
<option value="naver.com" selected>naver.com</option>
<option value="hanmail.net">hanmail.net</option>
<option value="yahoo.co.kr">yahoo.co.kr</option>
</select>
</div>
<div>
<label style="display:inline-block; width:110px">연락처</label>
<input type="text" v-model="user_phone">
</div>
<div>
<label style="display:inline-block; width:110px">주소</label>
<textarea cols="22" rows="10" v-model="user_addr"></textarea>
</div>
<div>
<label style="display:inline-block; width:110px">성별</label>
<input type="radio" value="male" v-model="user_gender">남자
<input type="radio" value="female" v-model="user_gender" >여자
</div>
<div>
<label style="display:inline-block; width:110px">관심과목</label>
<div style="display: inline-block;">
<input type="checkbox" value="backend" v-model="chk_subject" />backend
<input type="checkbox" value="frontend" v-model="chk_subject" />frontend<br>
<input type="checkbox" value="springboot" v-model="chk_subject" />spring boot
<input type="checkbox" value="oracle" v-model="chk_subject" />oracle<br>
</div>
</div>
<hr>
<div>
<span>약관에 동의하시겠습니까?</span>
<input type="checkbox" v-model="chk_info" v-on:change="checkInfo()">
<input type="button" value="회원가입" v-on:click="btnRegister()">
<router-link to="/vue/login1">
<input type="button" value="로그인"/>
</router-link>
</div>
</fieldset>
</div>
`,
data: function () {
return {
user_id: '',
user_pw: '',
user_pw_check: '',
user_name: '',
user_email: '',
user_email2: 'naver.com',
user_phone: '',
user_addr: '',
user_gender: '',
chk_subject: [],
chk_info: [],
password_check: false,
info_check: false
}
}, methods: {
checkPw() {
if (this.user_pw === '' || this.user_pw_check === '') {
alert('비밀번호를 입력해주세요.');
} else {
if (this.user_pw === this.user_pw_check) {
alert('비밀번호가 일치합니다.');
this.password_check = true;
return
} else {
alert('비밀번호가 일치하도록 입력해주세요.');
this.password_check = false;
return
}
}
},
checkInfo() {
if (this.chk_info.length === 1) {
alert('약관에 동의하셨습니다.');
this.info_check = true;
} else {
this.info_check = false;
}
},
btnRegister() {
if (this.user_id === '') {
alert('아이디를 입력하세요.');
return;
} else if (this.user_pw === '') {
alert('비밀번호를 입력하세요.');
return;
} else if (this.user_pw_check === '') {
alert('비밀번호를 입력 후 확인버튼을 눌러주세요.');
return;
} else if (this.user_name === '') {
alert('이름을 입력하세요.');
return;
} else if (this.user_email === '') {
alert('이메일을 입력하세요.');
return;
} else if (this.user_phone === '') {
alert('전화번호를 입력하세요.');
return;
} else if (this.user_addr === '') {
alert('사용자 주소를 입력하세요.');
return;
}else if (this.user_gender === '') {
alert('성별을 선택하세요.');
return;
}
try {
if(this.password_check === true && this.info_check === true) {
const sendData = {
userId: this.user_id,
userPw: this.user_pw,
userName: this.user_name,
userEmail: this.user_email,
userPhone: this.user_phone,
userAddr: this.user_addr,
userGender: this.user_gender,
chkSubject: this.chk_subject,
chkInfo: this.chk_info
}
const result = {
ret: 1
}
if(result.ret === 1){
alert('회원가입 성공하였습니다.');
this.$router.push({path:'/vue/home1'});
}
console.log(sendData);
}
} catch (error) {
console.error(error);
}
}
}
};
기본적인 구조와 동작은 로그인과 동일하고, 다른 부분에 대해서만 설명하겠다.
회원가입의 항목으로 아이디, 비밀번호, 비밀번호확인, 이름, 이메일, 휴대폰번호, 주소, 성별, 관심과목, 약관동의가 있다. 유효성 검사 이외에도 비밀번호가 동일하게 입력되었는지 검증하는 password_check변수와 약관에 동의를 받기위한 info_check변수를 선언하였다.
비밀번호 확인을 위한 checkPw메서드는 user_pw 필드와 user_pw_check필드의 값을 비교하여 일치하면 password_check를 true로 저장하고 아닐 경우 false로 저장한다.
약관의 경우도 체크가 표시되었을 경우 info_check를 true로 저장한다.
모든 항목이 비어있지 않고, 비밀번호확인과 약관동의가 체크되어있다면 회원가입 성공알림창을 사용자에게 출력한다.