Vue.js 에제 2
2019-11-26
vue 컴포넌트에서
npm i css-loader
npm i vue style-loader
<style scoped>
#screen {
width: 300px;
height: 200px;
text-align: center;
user-select: none;
}
#screen.waiting {
background-color: aqua;
}
#screen.ready {
background-color: red;
color: white;
}
#screen.now {
background-color: greenyellow;
}
</style>
scoped는 style이 해당 컴포넌트에만 적용되게 해준다.
<script>
let startTime = 0;
let endTime = 0;
let timeOut = null;
export default {
data() {
return {
result: [],
state: 'waiting',
message: '클릭해서 시작하세요',
}
},
computed: {
average() {
return this.result.reduce((a,c) => a+c, 0)/this.result.length || 0;
}
},
methods: {
onReset(){
this.result = [];
},
onClickScreen(){
if (this.state === 'waiting') {
this.state = 'ready';
this.message = '초록색이 되면 클릭하세요'
timeOut = setTimeout( () => {
this.state = 'now';
this.message ='지금 클릭!';
startTime = new Date();
}, Math.floor(Math.random() * 1000) + 2000); // 2~3초
} else if (this.state ==='ready'){
clearTimeout(timeOut);
this.state = 'waiting';
this.message = '너무 성급하시군요! 초록색이 된 후에 클릭하세요'
} else if (this.state === 'now') {
endTime = new Date();
this.state= "waiting";
this.result.push(endTime - startTime);
}
},
}
};
</script>
복잡한 로직은 반드시 computed 속성을 사용해야 한다.
average는 배열의 평균값, 혹은 배열이 비어있을 경우 0을 return한다.
setTimeout을 사용해서 함수를 지연 실행하고 clearTimeout으로 조건에 맞지 않을 경우 실행을 prevent한다.
<template>
<div>
<div id="screen" v-bind:class="state" v-on:click="onClickScreen"></div>
<div v-show = "result.length">
<div> 평균 시간: </div>
<button v-on:click="onReset"> 리셋 </button>
</div>
</div>
</template>
엘리먼트를 조건부로 표시하기 위한 옵션으로 v-show와 v-if가 있다.
reult 배열의 길이가 0이 아닐 경우에만 렌더링을 한다.
v-bind:class="state"
data() {
return {
state: 'waiting',
}
},
#screen.waiting {
background-color: aqua;
}
#screen.ready {
background-color: red;
color: white;
}
#screen.now {
background-color: greenyellow;
}
data의 state가 ‘waiting’, ‘ready’, ‘now’로 변할 때마다 class의 값이 바뀌고, 적용되는 스타일 역시 바뀐다.