국비교육(22-23)

39일차(1) : javascript로 작성했던 폼 Vue.js로 수정하기

서리/Seori 2022. 12. 1. 14:33

39일차(1) : javascript로 작성했던 폼 Vue.js로 수정하기

 

- 기존에 javascript로 작성했던 회원가입 폼(signup_form)을 Vue.js로 재작성해보기

2022.11.28 - [국비교육] - 36일차(2)/jsp(24) : 회원가입시 유효성 검증(validation) 기능 구현

 

 

 

div id="app" / el : "#app"

- 특정 요소(#app)안에서 일어나는 일을 vue로 관리하겠다는 뜻!
- form, body, div 등에 Vue에서 사용할 id를 부여한 후,
 아래에서 Vue 객체 생성(new vue) 하고, el: "선택자" 로 object 형식으로 작성해주면 된다.

 

- new Vue({}) 안의 {}는 object 형태로 작성하면 된다. { key:value, key2:value2, ... }


- 이 new Vue 안에서 사용하는 data를 model이라고 부른다.
- data: 를 object 형태로 선언하고 안에 여러 모델을 담으면 된다.

- data: 에 들어있는것은 초기값이다. 보통 다른함수에서 이 값을 바꿔준다.

- vue에서 관리하는 요소에서 사용할 함수목록들을 methods: 안에 작성한다. object 형태로!
- 특정 방에다가 함수를 집어넣은 형태이다.

- 메소드안에서 this.모델명 으로 해당 모델을 가리킬 수 있다.

 

new Vue({
    el:
    data:
    methods: 
})

 

- Vue 안의 각각이 무엇을 의미하는지 잘 알아두기!
- el: 어떤 요소를 관리할것인지 / data: 모델들의 목록 / methods: 동작의 목록

 

- 빨간색 키값은 고정, 안쪽의 초록색 키값은 마음대로 설정 가능!

- 어떤 값을 전달할 수도 있고 동작(함수실행)을 할 수도 있다.


 

<signup_form3>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/signup_form3.jsp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
<style>
	h1{
		 margin: 20px 0px 20px; 
		 border-bottom:3px solid #0d6efd; 
		 padding:10px 0px 10px;
	}
</style>
</head>
<body>
	<jsp:include page="/include/navbar.jsp">
	<jsp:param value="signupform" name="thisPage"/>
	</jsp:include>
	<div class="container">
		<h1>회원 가입 폼입니다.</h1>		
		<form v-on:click="onSubmit" action="signup.jsp" method="post" id="signupForm">
		<p>폼의 유효성 여부 : <strong>{{isFormValid}}</strong></p>
			<div class="mb-2">
			 	<label for="id" class="control-label">아이디</label>
			 	<input 
			 		v-on:input="onIdInput" 
			 		v-model="id"
			 		v-bind:class="{'is-valid':isIdValid, 'is-invalid':!isIdValid && isIdDirty }" 
			 		type="text" class="form-control" name="id" id="id" />
			 	<div class="valid-feedback">사용할 수 있습니다.</div>
			 	<div class="invalid-feedback">사용할 수 없는 아이디입니다.</div>
			</div>
			<div class="mb-2">
				<label for="pwd" class="control-label">비밀번호</label>
				<input 
					v-on:input="onPwdInput" 
			 		v-model="pwd"
			 		v-bind:class="{'is-valid':isPwdValid, 'is-invalid':!isPwdValid && isPwdDirty }"				
					type="password" class="form-control" name="pwd" id="pwd" />
				<div class="invalid-feedback">비밀번호를 확인하세요.</div>
			</div>
			<div class="mb-2">
				<label for="pwd2" class="control-label">비밀번호 확인</label>
				<input
					v-on:input="onPwdInput" 
			 		v-model="pwd2" 
					type="password" class="form-control" name="pwd2" id="pwd2" />
			</div>
			<div class="mb-2">
				<label for="email" class="control-label">이메일</label>
				<input
					v-on:input="onEmailInput" 
			 		v-model="email"
			 		v-bind:class="{'is-valid':isEmailValid, 'is-invalid':!isEmailValid && isEmailDirty }"  
					type="text" class="form-control" name="email" id="email" />
				<div class="invalid-feedback">이메일 형식에 맞게 입력하세요.</div>
			</div>	
			<button v-bind:disabled="!isFormValid" class="btn btn-primary" style="margin-top: 10px;" type="submit">회원가입</button>			
		</form>
	</div>
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	<script>
		new Vue({
	        el:"#signupForm",
	        data:{
	           isIdValid:false,
	           isPwdValid:false,
	           isEmailValid:false,
	           id:"",
	           email:"",
	           pwd:"",
	           pwd2:"",
	           isIdDirty:false,
	           isEmailDirty:false,
	           isPwdDirty:false,	           
	        },
	        computed:{
	        	isFormValid(){
	        		//모델을 활용해서 얻어낼 값이 있으면 얻어낸다.
	        		let result=this.isIdValid && this.isPwdValid && this.isEmailValid;
	        		//함수에서 리턴해주는 값을 모델처럼 사용하면 된다.
	        		return result;
	        	}
	        },
	        
	        methods:{
	        	onSubmit(e){
	        		//폼 전체의 유효성 여부
	        		//const isFormValid= this.isIdValid && this.isPwdValid && this.isEmailValid;
	        		//만일 폼이 유효하지 않으면
	        		if(! this.isFormValid){
	        			e.preventDefault();
	        		}
	        	},
	        	
	        	onPwdInput:function(){
	        		this.isPwdDirty=true;
	        		//비밀번호를 검증할 정규 표현식
	        		const reg=/[\W]/; 
	    			//만일 정규표현식 검증을 통과하지 못했다면
	    			if(!reg.test(this.pwd)){	    				
	    				this.isPwdValid=false;
	    				return;	//함수를 여기서 끝내라     
	    	        }
	    			
	    			//만일 비밀번호 입력란과 확인란이 다르다면
	    			if(this.pwd != this.pwd2){	    				
	    				this.isPwdValid=false;
	    			}else{ //같다면		
	    				this.isPwdValid=true;
	    			}			
	        	},
	        	
	        	onEmailInput:function(){
	        		this.isEmailDirty=true;
	        		//이메일을 검증할 정규표현식
					const reg=/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i;									
					//만일 입력된 이메일이 정규표현식 검증을 통과하지 못했다면
					if(!reg.test(this.email)){
						this.isEmailValid=false;						
					}else{
						this.isEmailValid=true;
					};
					
	        	},
	        	
	        	
				onIdInput:function(){
				//아이디를 한번이라도 입력하면 아이디가 더럽혀 졌는지 여부를 true 로 바꿔준다. 
				this.isIdDirty=true;

				//아이디를 검증할 정규표현식
				const reg=/^[a-z].{4,9}$/;
				//입력한 아이디가 정규표현식과 매칭이 되는지(통과 되는지) 확인한다. 
				const isMatch=reg.test(this.id);
				//만일 매칭되지 않는다면
				if(!isMatch){
					this.isIdValid=false;
					return; //함수를 여기서 끝내라
				}
				
				//Vue 객체의 참조값을 self 에 담기
				const self=this;
				
				//2. 서버에 페이지 전환없이 전송을 하고 응답을 받는다.
				fetch("checkid.jsp?inputId="+this.id)
				.then(function(response){
					return response.json();
				})
				.then(function(data){
				   //3. 사용가능한지 여부에 따라 아이디 입력란에 is-valid or is-invalid 클래스를 적절히 추가, 제거를 한다.
				   console.log(data);
				   if(data.isExist){   
				      self.isIdValid=false;
				   }else{
				      self.isIdValid=true;
				   }
				});
	          	}
	        }
		});		
		
	</script>	
	<jsp:include page="/include/footer.jsp"></jsp:include>
</body>
</html>

- signupform을 vue 기반으로 동작하도록 수정하기!

 

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">
- vue cdn링크 추가

 

 

- javascript에서는 변수인 것들을 vue안에서 모델로 선언할 필요가 있다.

- vue로 제어하고 관리한다!

 

data:{
    isIdValid:false,
    isPwdValid:false,
    isEmailValid:false
}

 

 

 

 

- methods 안에는 각각의 input요소에 어떤 이벤트가 일어났을 때 실행할 함수 작업하기

- 이벤트 처리는? 해당 요소 안에 이벤트를 넣는다. (v-on:input)

 

- 빨간색: 정해져있는 값

- 파란색: 필요에따라 내가 지을수있는 이름!

 

- 괄호 안의 어디를 작성하고 있는지, 어떤 타입을 작성하고 있는지 잘 파악해야 한다!

 (읽어오기, 정규표현식 복사해오기)

 

- input 요소에 v-model 모델명을 지정하고, Vue data에 초기값을 id:" " 로 넣어준다.

 

- 모델을 하나 지정한다는 것은 여기에 입력한 값을 실시간으로 본다는 것!

 

- 안에서 참조하려면 this.id로 참조할 수 있다.

 

- isIdValid는 모델로 관리하고있다.

- 함수 if문 안에서 값(실제 값, 클래스 등)이 달라지면 isIdValid의 실제 값도 바뀐다.

 

- if 문 안에는 클래스 추가하는 코드. 

- true면 is-valid 클래스 / false면 is-invalid 클래스

 

v-bind:class="{'is-valid':isIdValid, 'is-invalid':!isIdValid }" 를 모델에 추가

- 여기서는 this. 필요없이 모델명을 바로 적으면 된다.

 

- vue로 클래스를 제어하고 있는 것을 console에서 확인 가능

 

- fetch 부분은 위와 같이 수정한다.

 

- 하지만 여기서 this는 fetch를 가리킨다. fetch문 바깥은 참조가 되지 않는다.

- 글로벌영역에서 사용하는 this가 똑같이 적용되려면, 어딘가에 담아놓아야 한다.

 

- fetch문 위에서 const self=this; 로 변수를 만들어두고 self를 참조하여 사용한다.

 

- 위에서 const app = new Vue({ }) 로 미리 변수에 담아두고, app. 으로 사용해도 된다.

 


 

- isIdValid의 초기값이 false라서 폼을 열자마자 빨간색으로 에러 메시지가 나온다.

- 이런 것은 보기 좀 그렇다.. 뭔가를 입력하면 그때부터 검증하면 된다!

- 이전에는 입력(input)을 기준으로 그때부터 검증이 일어났는데 지금은 기본값이 false이기때문에 발생하는 문제.

 

- 해결을 위해서는 값을 하나 더 써주어야 한다.

- v-bind에 다른 조건이 하나 더 들어가야 한다.

 

- isIdDirty라는 모델을 만들어준다.

- isIdDirty:false : 한번이라도 값을 입력했는지 여부를 t/f로 반환

- input에 한번이라도 값을 입력했을 때 에러메시지를 띄워야한다!

 

- isIdValid와 isIdDirty가 둘다 true여야만(&&) ID 조건이 성립하도록 코딩하기

 


 

- 이메일도 3개의 data를 추가해준다.

 

onEmailInput:function(){ }

onEmailInput(){ }

- 두개는 같은 식! 아래와 같이 쓸 수 있다.(javascript의 새 문법)

 


 

- 비밀번호 수정

 

- 두개의 인풋요소에 onPwdInput이라는 같은 함수를 적용한다.

- pwd2 도 모델로 관리한다.

 


 

onSubmit(e){}

- Vue에 어느 하나라도 false이면 폼 제출을 막을 메소드 추가

 

- 폼 유효성을 확인하고 submit으로 제출하는 코드

onSubmit(e){    
    const isFormValid= this.isIdValid && this.isPwdValid && this.isEmailValid;    
    if(!isFormValid){
        e.preventDefault();
    }
}

 

 

- 그런데 폼 전체의 유효성 여부도 자동으로 계산되도록 모델로 만들 수는 없을까?

- 어떤 모델이 다른 것의 값을 확인하고 자기의 값을 바꾸는 일도 할 수 있다.

 

data:{ isFormValid: this.isIdValid && this.isPwdValid && this.isEmailValid } 추가

- 하지만 이렇게 하면 {{ }} 으로 출력되지 않는다. 내용이 바뀌어도 값도 달라지지 않는다.ㅠㅠ

 

 

computed:

- 모델로 관리되는 값을 가지고 뭔가를 도출해 낼 때는 computed를 활용한다.

- 모델을 활용한 계산된 값을 얻어내고 싶을 때, 그리고 그 값을 모델처럼 사용하고 싶을 때 사용.

 

computed:{
     isFormValid(){}
}

 

- computed: 안에 함수로 선언한다.

- isFormValid 라는 모델이 있는 것처럼 사용하면 된다! 함수를 호출할 필요가 없다.

- 함수 안에서 리턴한 값이 모델 역할을 하는 것이나 마찬가지다.

 

- 유효성 여부 : {{isFormValid}} 라고만 작성해도 위와 같이 출력된다.

 

computed:{ 함수명(){} }

- 모델을 사용해 값을 도출하는 함수를 모델처럼 활용하는 방법!

 


 

 

- 버튼에 disabled를 하면 클릭되지 않는다.

- 폼 전체의 유효성 t/f를 사용해서 disabled 적용하기!

 

<button v-bind:disabled="!isFormValid">

- 버튼에 disabled를 동적으로 추가해 준다.

 

-모든 조건에 통과되면 유효성 여부:true 로 바뀌고 회원가입 버튼이 활성화된다!

- disabled 속성도 vue로 제어할 수 있다.

 

 

- 이런 js 라이브러리 중 비슷한 종류들. vue가 제일 쉽다...ㅎㅎ

 

- UI를 정의할때 다양한 라이브러리가 필요할 수 있다.

- 같은 내용의 코드라도 다양한 라이브러리를 사용해서 작성해보기!

 

'국비교육(22-23)' 카테고리의 다른 글

40일차(1) : Vue.js 예제(4)  (0) 2022.12.04
39일차(2) : Vue.js 예제(3)  (0) 2022.12.01
38일차(3) : Vue.js 예제(2)  (0) 2022.12.01
38일차(2) : Vue.js 예제(1)  (1) 2022.12.01
38일차(1) : 정규 표현식  (0) 2022.11.30