본문 바로가기
  • 문과생의 백엔드 개발자 성장기
|Playdata_study/JavaScript

210910_Vue.js(event : v-cloak, v-once)

by 케리's 2021. 9. 10.

• 복습 

 

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<link rel="stylesheet" type="text/css" href="./table.css"/>
<title>ENCORE</title>
  <script src="https://unpkg.com/vue"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
</head>
<body>
<div id='app'>
<div class='headtitle'><h2>KERY HRM LIST</h2></div>
<div class='search_box'>
<a href='./index04.html'>사원추가</a> | 
<a href='./index03.html'>이름으로 찾기</a> |
<a href='./index02.html'>아이디로 찾기</a> |
<a href='./index01.html'>모든사원 보기</a>
</div>
<table class='list_table'>
<col width="10%"><col width="20%">
<col width="20%"><col width="20%"><col width="10%">
<thead>
<tr>
  <th>사원 아이디</th>
  <th>사원명</th>
  <th>부서</th>
  <th>직책</th>
  <th>연봉</th>
</tr>
</thead>
<tbody>
<!--  여기에 <tr v-for -->
     <tr v-for="emp in emps"> 
     <!-- <tr v-for="emp in emps" v-if="emp.id==1"> -->
         <td>{{emp.id}}</td>
         <td>{{emp.name}}</td>
         <td>{{emp.dept_id}}</td>
         <td>{{emp.title}}</td>
         <td>{{emp.salary | salarydecimal}}</td>
     </tr>
<tr>
</tr>
</tbody>
</table>
</div>
<script type="text/javascript">
	new Vue({
	    el: '#app',
	    data:{
	    	emps:[{
	            "id": 1,
	            "name": "박길곤",
	            "mailid": "sky98",
	            "start_date": "1990-03-03",
	            "manager_id": 0,
	            "title": "사장",
	            "dept_id": 118,
	            "salary": 5000.0,
	            "commission_pct": 0.0
	        }, {
	            "id": 2,
	            "name": "손민성",
	            "mailid": "2xxsig",
	            "start_date": "1990-03-08",
	            "manager_id": 1,
	            "title": "기획부장",
	            "dept_id": 110,
	            "salary": 3000.0,
	            "commission_pct": 0.0
	        }, {
	            "id": 3,
	            "name": "이지선",
	            "mailid": "ch21175",
	            "start_date": "1991-06-17",
	            "manager_id": 1,
	            "title": "영업부장",
	            "dept_id": 102,
	            "salary": 3500.0,
	            "commission_pct": 0.0
	        }, {
	            "id": 4,
	            "name": "서가홍",
	            "mailid": "mquickto",
	            "start_date": "1990-04-07",
	            "manager_id": 1,
	            "title": "총무부장",
	            "dept_id": 101,
	            "salary": 3000.0,
	            "commission_pct": 0.0
	        }]
	    },
	    
	    filters:{
	    	salarydecimal(value){
	    		return value.toFixed(2)
	    	}
	    }
	   
	})
 </script>
</body>
</html>

 

 

/* table. css*/

@CHARSET "UTF-8";
/* input elements */
input		{font-size:12px;}
textarea	{font-size:12px;}
input.txt	{padding-top:3px; height:18px;}
select		{font-size:12px; height:20px;}		
 .headtitle  { margin:auto; padding:0px; text-align:center; color: #696966; font-family: serif;}	
 .headtitle  > h2 { margin:auto; padding:0px; text-align:center; color: #696966; font-family: serif; }	
	.list_table { width:98%; border-bottom:1px solid #EFEFEF; border-right:1px solid #EFEFEF; border-collapse:collapse; margin-left:auto; margin-right:auto; clear:both; }
	.list_table2 { width:98%; border-bottom:1px solid #EFEFEF; border-right:1px solid #EFEFEF; border-collapse:collapse; margin-left:auto; margin-right:auto; clear:both; vertical-align:middle; text-align: center}
	.list_table td,.list_table th { text-align:center; border-top:1px solid #EFEFEF; border-left:1px solid #EFEFEF; padding:0.3em; }
	.list_table th { background-color:#ff7373; color:#FFFFFF; line-height:1.7em; font-weight:normal;}
	.list_table tr td { padding-top:0.5em; padding-bottom:0.5em;}	
	.list_table td.title { padding-left:0.5em; text-align:left; }
	.list_table td.title a:hover { text-decoration:underline; }
	.list_table th, .list_table td { vertical-align:middle; }	

	.list_table select { height:19px; border:#CCCCCC solid 1px; vertical-align:middle; line-height: 1.8em; padding-left:0px; }
	.list_table select option { margin-right:10px; }
	.list_table .selected_row { border:solid 0px #EFEFEF; }
	.list_table .sele { padding:0; margin:0; }
			
	.content_table { width:98%; border-bottom:1px solid #EFEFEF; border-right:1px solid #EFEFEF; border-collapse:collapse; margin-left:auto; margin-right:auto;  clear:both; }
	.content_table td, .content_table th { text-align:center; border-top:1px solid #EFEFEF; border-left:1px solid #EFEFEF; padding:0.3em; }
	.content_table th { background-color:#ff7373; color:#FFFFFF; line-height: 1.7em; font-weight:normal;}
	.content_table td { padding-left:5px; text-align:left; line-height: 1.7em; }
	.content_table td.contents { width:100%; height:400px; overflow:auto; }
	
	.content_table th, .content_table td { vertical-align:middle; }

	.content_table select { height:19px; border:#CCCCCC solid 1px; vertical-align:middle; line-height: 1.8em; padding-left:0px; }
	.content_table select option { margin-right:10px; }
			
	#files_wrap { width:99.5%; margin-left:auto; margin-right:auto; }
	#files_wrap #_file_list_item { list-style-type:disc; }
	
	.box_border { width:98%; border-width:1px; border-style:solid; border-color:#EFEFEF; background-color:#FFFFFF; text-align:right; padding:2px; margin-top:5px; margin-bottom:10px; margin-left:auto; margin-right:auto;}
	.search_box { width:98%; border-width:1px; border-style:solid; border-color:#EFEFEF; background-color:#FFFFFF; padding:2px; padding-top:7px; padding-bottom:7px; margin-top:5px; margin-bottom:10px; margin-left:auto; margin-right:auto; margin-top:5px; margin-bottom:10px; text-align:center; line-height:2.1em;}

	.items_title { text-align:left; margin-left:auto; margin-right:auto; padding-left:28px; padding-top:3px; background-image:url("../image/shape_square.png"); background-repeat:no-repeat; background-position:10px 0px; margin-top:25px; margin-bottom:1px; font-size:12px; font-weight:bold; }
	.items_description { width:98%; border-width:1px; border-style: solid; border-color:#EFEFEF; background-color:#FFFFFF; text-align:left; line-height:2.5; padding:2px; margin:0px;}

	.checkbox_lable {
		vertical-align:2px; margin-left:5px; margin-right:5px;
		_vertical-align:4px; _margin-left:0px; _margin-right:2px;   /* IE6 Hack */
	}

	.go_view { cursor:pointer; text-align:left; padding-left:3px;}
	
	.calendar_icon { cursor:pointer; border:0; width:22px; vertical-align:-6px; *vertical-align:-6px; }
	
	.tored {color:#aabbcc;background-color: #ddbbaa}

 

 

 

 

 

<!-- v-if 로 조건식 주기 -->

<tbody>
     <tr v-for="emp in emps" v-if="emp.id==1">
         <td>{{emp.id}}</td>
         <td>{{emp.name}}</td>
         <td>{{emp.dept_id}}</td>
         <td>{{emp.title}}</td>
         <td>{{emp.salary | salarydecimal}}</td>
     </tr>
<tr>

 

 

 

 

 

• computed : 알고리즘 구현 결과를 속성 값으로 접근

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> 알고리즘 구현 결과를 속성 값으로 접근 :: computed</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id = "app">
	<input type="text" v-model="num"><br/>
	<!-- 1. {{}} 에서 method 는 ()를 붙여야한다, v-text도 마찬가지 -->
	<!-- 1부터 입력된 수까지 총 합 :: <span>{{sum()}}</span>  -->
	
	<!-- 2. {{}} 에서 computed는 ()를 제외해야함 -->
	1부터 입력된 수까지 총 합 :: <span>{{sum}}</span> 
	
</div>

<script type="text/javascript">

	// 1. method
/* 	new Vue({
		el:'#app',
		data:{num:0}, // v-model="num" 이것이 있다는 얘기는 data:{num:0} 바인딩 되어야 한다는 말
		methods:{ //알고리즘을 돌리려면 methods 기능이 있어야함
			sum:function(){ // == sum(){} 이랑 같음
				var n = Number(this.num);
				if(Number.isNaN(n) || n < 1) return 0; //문자이거나 음수 넣지말자
				return((1+n)*n)/2;
			}
		}
		
	}); */
	
	// 2. computed
	new Vue({
		el:'#app',
		data:{num:0}, // v-model="num" 이것이 있다는 얘기는 data:{num:0} 바인딩 되어야 한다는 말
		computed:{ 
			sum(){
				var n = Number(this.num);
				if(Number.isNaN(n) || n < 1) return 0; //문자이거나 음수 넣지말자
				return((1+n)*n)/2;
			}
		}
		
	});

</script>
</body>
</html>

 

1-10 까지 더하면 55

 

 

 

event 

 

v-if | v-else-if | v-else

 

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>v-if | v-else-if | v-else</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id = "app">
	<div v-html="title"></div>
	<input type="text" v-model="grade">
	<div v-if="grade=='A'"><h3>v-if 실행 :: A grade</h3></div>
	<div v-else-if="grade=='B'"><h3>v-else-if 실행 :: B grade</h3></div>
	<div v-else><h3>v-else 실행 :: Try Again</h3></div> <!-- 위 2개가 아니면 else가 출력 -->
</div>

<script type="text/javascript">
	var app = new Vue({
		el:'#app',
		data:{
			title:'Banana',
			grade:'A'
		}
	});

</script>
</body>
</html>

 

 

 

 

 v-bind

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Vue Css -->

<style type="text/css">
	#flag_section{
		width: 800px;
		height:200px;
		margin: 0 auto; /* margin 값을 0 auth로 하려면 width 를 %로 주지말고 px값으로 정확하게 해줘야함*/
		padding: 20px;
		text-align: center;
		font-size: 14px;
	}
	#tid{
		width:600px;
		margin: 0 auto;
		
	}
</style>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<div id="flag_section">
	<h2>National Flags</h2>
	<table id="tid" border="1px">
		<thead>
			<tr>
				<th>나라이름1</th><th>나라이름2</th><th>국기</th>
			</tr>
		</thead>
		
		<tbody>
			<tr v-for="flag in flags">
				<td>{{flag.name}}</td>
				<td>{{flag.korname}}</td>
				<td><img :src="flag.flag"></td> <!-- v-bind -->
			</tr>
		</tbody>
	</table>
</div>

<script type="text/javascript">
	var model = {
			flags:[
				{
					name:'Ghana',
					korname:'가나',
					flag:'https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Flag_of_Ghana.svg/44px-Flag_of_Ghana.svg.png'
				},
				{
					name:'south_Korea',
					korname:'대한민국',
					flag:'https://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Flag_of_South_Korea.svg/44px-Flag_of_South_Korea.svg.png'
				}
			]
	}
	new Vue({
		el:'#flag_section',
		data:model
	});

</script>
</body>
</html>

 

 

 

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Vue Css -->

<style type="text/css">
	#flag_section{
		width: 800px;
		height:200px;
		margin: 0 auto; /* margin 값을 0 auth로 하려면 width 를 %로 주지말고 px값으로 정확하게 해줘야함*/
		padding: 20px;
		text-align: center;
		font-size: 14px;
	}
	#tid{
		width:600px;
		margin: 0 auto;
		
	}
</style>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
<div id="flag_section">
	<h2>National Flags</h2>
	<template v-for="flag in flags">
		<label><span>{{flag.name}}</span></label>
		<input type="text" :value="flag.korname">&nbsp;&nbsp;&nbsp;&nbsp;
		<img :src="flag.flag">
		<br/>
	</template>
</div>

<script type="text/javascript">
	var model = {
			flags:[
				{
					name:'Ghana',
					korname:'가나',
					flag:'https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Flag_of_Ghana.svg/44px-Flag_of_Ghana.svg.png'
				},
				{
					name:'south_Korea',
					korname:'대한민국',
					flag:'https://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Flag_of_South_Korea.svg/44px-Flag_of_South_Korea.svg.png'
				}
			]
	}
	new Vue({
		el:'#flag_section',
		data:model
	});

</script>
</body>
</html>

 

 

 

 

 v-if , computed

 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>encore</title>
<style type="text/css">
	#tlist{ width: 400px; border: 1px solid black; border-collapse: collapse;}
	#tlist td, #tlist th{ border: 1px solid black; text-align: center;}
	#tlist>thead>tr{color: #ffe4e1; background: #f7347a; }

</style>
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
</head>
<!-- 
	v-pre
	::
	이 디렉티브는
	해당 태그와 그 자식태그들 모두가 Vue 문법을 따르지 않는 영역임을 지정하는 문법이다.
 -->
<body>    
	<div id="example">
	<!-- <div v-pre]>{{countryname}}</div> -->
		<p>
			국가명 : <input type="text" placeholder="국가명을 입력"  v-model="countryname"
			v-on:input="countryname=$event.target.value">
		</p>
		<table id="tlist">
			<thead>
				<tr>
					<th>번호</th><th>국가명</th><th>수도</th><th>지역</th>
				</tr>
			</thead>
			
			<!-- 
			* 조건 주기
			//1.
			<tr v-for="c in countries" v-if="c.name.includes(countryname)">
			
			//2. computed :: 현재 적용되어 있음
			
			-->
			
			
			<tbody>
				<!-- <tr v-for="c in countries"> -->
				<tr v-for="c in filtering">
					<td>{{c.no}}</td>
					<td>{{c.name}}</td>
					<td>{{c.capital}}</td>
					<td>{{c.region}}</td>
				</tr>
			</tbody>
		</table>
	</div>
    <script type="text/javascript">
	var model = {
      	//필요한 모델데이타가 있으면 추가하시기 바랍니다.
      	countryname : '', // v-model="countryname" 의 초기값 주기
	    countries : [
            { no:1,  name : "미국", capital : "워싱턴DC", region:"america" },
            { no:2,  name : "프랑스", capital : "파리", region:"europe" },
            { no:3,  name : "영국", capital : "런던", region:"europe" },
            { no:4,  name : "중국", capital : "베이징", region:"asia" },
            { no:5,  name : "태국", capital : "방콕", region:"asia" },
            { no:6,  name : "모로코", capital : "라바트", region:"africa" },
            { no:7,  name : "라오스", capital : "비엔티안", region:"asia" },
            { no:8,  name : "베트남", capital : "하노이", region:"asia" },
            { no:9,  name : "피지", capital : "수바", region:"oceania" },
            { no:10,  name : "솔로몬 제도", capital : "호니아라", region:"oceania" },
            { no:11,  name : "자메이카", capital : "킹스턴", region:"america" },
            { no:12,  name : "나미비아", capital : "빈트후크", region:"africa" },
            { no:13,  name : "동티모르", capital : "딜리", region:"asia" },
            { no:14,  name : "멕시코", capital : "멕시코시티", region:"america" },
            { no:15,  name : "베네수엘라", capital : "카라카스", region:"america" },
            { no:16,  name : "서사모아", capital : "아피아", region:"oceania" }
   	    ]
    }   
	
/* 	var clist = new Vue({
		el:'#example',
		data:model */
		
	var clist = new Vue({
		el:'#example',
		data:model,
		computed:{
			filtering(){ // 배열 아이템 중에서 조건을 만족하는 아이템을 걸러서 새로운 배열을 만들어서 리턴
				var cname = this.countryname.trim(); // 앞 공백 제거
				return this.countries.filter(function(item, index){
					if(item.name.indexOf(cname)>-1)
					return true;
				});
			}	
		}
		
	});
    </script>
</body>
</html>

 

 

 

 

 

 computed

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SAFE FOOD</title>
<style type="text/css">
	#second>h2{ width: 850px; height: 30px; margin: 0 auto; padding: 20px; text-align: center;}
	#checkboxArea1 { width: 850px; height: 30px; margin: 0 auto; padding: 20px; text-align: center; font-size: 13px;}
	#checkboxArea2 { width: 850px; height: 30px; margin: 0 auto; padding: 20px; text-align: center; font-size: 13px; color: red;}
 
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
	<div id="second">
		<h2>KERY SAFE FOOD</h2>
	</div>
	<div id="app">
		<fieldset id="checkboxArea1">
			<legend>알레르기 체크</legend>
			<input type="checkbox" name="box" value="대두" v-model="alergen"><label>대두</label>
			<input type="checkbox" name="box" value="땅콩" v-model="alergen"><label>땅콩</label>
			<input type="checkbox" name="box" value="우유" v-model="alergen"><label>우유</label>
			<input type="checkbox" name="box" value="게" v-model="alergen"><label>게</label>
			<input type="checkbox" name="box" value="새우" v-model="alergen"><label>새우</label>
			<input type="checkbox" name="box" value="참치" v-model="alergen"><label>참치</label>
			<input type="checkbox" name="box" value="연어" v-model="alergen"><label>연어</label>			
			<input type="checkbox" name="box" value="쑥" v-model="alergen"><label>쑥</label>
			<input type="checkbox" name="box" value="쇠고기" v-model="alergen"><label>쇠고기</label>
			<input type="checkbox" name="box" value="닭고기" v-model="alergen"><label>닭고기</label>
			<input type="checkbox" name="box" value="돼지고기" v-model="alergen"><label>돼지고기</label>
			<input type="checkbox" name="box" value="복숭아" v-model="alergen"><label>복숭아</label>
			<input type="checkbox" name="box" value="민들레" v-model="alergen"><label>민들레</label>
			<input type="checkbox" name="box" value="달걀흰자" v-model="alergen"><label>달걀흰자</label>
		</fieldset>		
	
		<fieldset id="checkboxArea2" v-if="moreZero">
			알러지 요인들 : <span v-html="alergen"></span>
		</fieldset>
	
	</div>
	<script>
		var app = new Vue({
			el:'#app',
			data:{
				alergen:[ ]//초기화는 []로간다.
			},
			computed:{
				moreZero(){
					return this.alergen.length>0;
				}
			}
		})
	</script>
</body>
</html>

 

 

 

• v-cloak 디렉티브

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- 
	v-cloak 디렉티브
	:: 
	자바 스크립트의 로딩이 끝나기 전까지
	즉, VueModel에서 동적으로 받아온 데이터를 화면에 랜더링하기 전까지
	화면에 남아있는 Vue문법이 노출되지 않도록 가려주는 역할을 한다.
	해당 부분을 display:none 으로 설정하는데 v-cloak디렉티브 문법을 적용한다.

 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
	[v-cloak] {display: none;} 
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
	<div id="app">
		<h2 v-cloak>{{title}}</h2>
	</div>
	
	<script type="text/javascript">
	setTimeout(() => {
		new Vue({
			el:'#app',
			data:{title:"안녕하세요"}
		});
	}, 2000); //2초뒤에 {{}}안에 데이터로 랜더링이 진행된다

	</script>
</body>
</html>

 

2초 뒤에 생성됨

 

 

 

 

• v-once 

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<!-- 
	v-once
	::
	해당 엘리먼트를 단 한번만 랜더링 한다는 뜻
	이 문법이 어떤 경우에 사용되는지 간략히 정리
	
	정적인 엘리먼트를 처리할 때 사용된다.
	이 부분은 랜더링이 단 한번만 진행된다.
 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
	<h2 v-once>{{'초기값 : ' + count}}</h2>
	<h2>{{'증가된 값 : '+ count}}</h2>
	<button @click="count++">+</button>
</div>

<script type="text/javascript">
	new Vue({
		el:'#app',
		data:{
			count:1
		}
		
	});

</script>
</body>
</html>

 

 

 

 

• submit 이벤트

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- 
	이벤트
	1) 클릭 이벤트
	2) 키 이벤트
	3) INPUT 이벤트
	4) submit 이벤트
 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
	<form action="vue07_vonce.html" @submit.prevent="datacheck">
		아이디<input type="text" id="id" v-model="id" placeholder="아이디를 입력">
		<button @click="sendId">결과보기</button>
		<label><input @keyup.enter="submit">키엔터</label> <!-- 추가 :: 엔터누르면 이벤트 발생 -->
	</form>
</div>

<script type="text/javascript">
	new Vue({
		el:'#app',
		data:{
			id:''
		},
		methods:{
			sendId(){
				alert(this.id);
			},
			datacheck(){
				//if(this.id=="")
				alert(document.getElementById("id").getAttribute("placeholder"));
			}
		}
	});
</script>
</body>
</html>

 

 

댓글