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의 값이 바뀌고, 적용되는 스타일 역시 바뀐다.