...
methods:{
attackMonster(){
const attackValue = getRandomValue(12, 5)
this.monsterHealth -= attackValue
this.attackPlayer()
},
attackPlayer(){
const attackValue = getRandomValue(15, 8)
this.playerHealth -= attackValue
}
}
...
위 코드는 가장은 스크립트 게임을 만들어보는 과정이다. 코드를 보면 4번째 줄에 this.attckplayer를 확인할 수 있는데 이를 자세히 보면
this 키워드를 사용하면 data 프로퍼티도 액세스할 수 있고 Vue 인스턴스 구성 객체 내의 method도 액세스할 수 있다.
작동 원리는 data 프로퍼티의 경우와 같다. method나 computed 프로퍼티의 경우도 마찬가지이다 모두 다 내부에서 관리되는 전역적 객체로 통합되기 때문이다.
그렇기 때문에 methods 내에서 this 키워드를 사용해서 data 프로퍼티에 액세스하는 것과 같이 methods 내의 메서드도 액세스하고 호출할 수 있다.
내부
}) 와 외부
에 선언되는 차이점은 무엇일까?Vue 인스턴스 내부에서 액세스를 해야하는 경우
Vue 인스턴스 값이 바뀌면 Vue가 인지해야하는 경우
<div id="game">
<section id="monster" class="container">
<h2>Monster Health</h2>
<div class="healthbar">
<div class="healthbar__value" :style="monsterBarStyle"></div>
</div>
</section>
<section id="player" class="container">
<h2>Your Health</h2>
<div class="healthbar">
<div class="healthbar__value" :style="playerBarStyle"></div>
</div>
</section>
<section class="container" v-if="winner">
<h2>game over!</h2>
<h3 v-if="winner === 'player'">you win!</h3>
<h3 v-else-if="winner === 'monster'">you lost!</h3>
<h3 v-else>draw!</h3>
<button @click="startGame">start new game!</button>
</section>
<section id="controls" v-else>
<button @click="attackMonster">ATTACK</button>
<button :disabled="mayUseSpecialAttack" @click="specialAttackMonster">SPECIAL ATTACK</button>
<button @click="healPlayer">HEAL</button>
<button @click="surrender">SURRENDER</button>
</section>
<section id="log" class="container">
<h2>Battle Log</h2>
<ul>
<li v-for="logMessage in logMessages">
<span :class="{'log--player':logMessage.actionBy === 'player', 'log--monster': logMessage.actionBy === 'monster'}">
{{logMessage.actionBy === 'player' ? 'Player' : 'Monster'}}
</span>
<span v-if="logMessage.actionType === 'heal'">
heals <span class="log--heal">{{logMessage.actionValue}}</span>
</span>
<span v-else>
attacks <span class="log--damage">{{logMessage.actionValue}}</span>
</span>
</li>
</ul>
</section>
</div>
const getRandomValue = (max, min) => {
return Math.floor(Math.random()*(max-min))+min
}
const app = Vue.createApp({
data(){
return{
playerHealth : 100,
monsterHealth : 100,
currentRound:0,
winner:null,
logMessages : []
}
},
computed:{
monsterBarStyle(){
if(this.monsterHealth <= 0) {
return {width: 0}
}
return {width:this.monsterHealth+'%'}
},
playerBarStyle(){
if(this.playerHealth <= 0){
return {width: 0}
}
return {width: this.playerHealth+'%'}
},
mayUseSpecialAttack(){
return this.currentRound % 3 !== 0
}
},
watch:{
playerHealth(value){
if(value<=0 && this.monsterHealth<=0){
this.winner = "draw"
} else if (value <= 0){
this.winner = "monster"
}
},
monsterHealth(value){
if(value<=0 && this.playerHealth<=0){
this.winner = "draw"
} else if (value <= 0){
this.winner = "player"
}
}
},
methods:{
attackMonster(){
this.currentRound++
const attackValue = getRandomValue(12, 5)
this.monsterHealth -= attackValue
this.addLogMessage("player","attack",attackValue)
this.attackPlayer()
},
attackPlayer(){
const attackValue = getRandomValue(15, 8)
this.addLogMessage("monster","attack",attackValue)
this.playerHealth -= attackValue
},
specialAttackMonster(){
this.currentRound++
const attackValue = getRandomValue(10, 25)
this.monsterHealth -= attackValue
this.addLogMessage("player","special-attack",attackValue)
this.attackPlayer()
},
healPlayer(){
this.currentRound++
const healValue = getRandomValue(8,20)
if(this.playerHealth+healValue>100){
this.playerHealth = 100
} else {
this.playerHealth += healValue
}
this.addLogMessage("player","heal",healValue)
this.attackPlayer()
},
startGame(){
this.playerHealth = 100,
this.monsterHealth = 100,
this.currentRound = 0,
this.winner = null,
this.logMessages = []
},
surrender(){
// this.addLogMessage("player","surrender")
this.winner="monster"
},
addLogMessage(who, what, value){
this.logMessages.unshift({
actionBy : who,
actionType : what,
actionValue : value
})
}
}
})
app.mount("#game")
array의 메서드중 하나로 push
는 배열 맨 마지막
, unshift
는 배열 맨 처음
에 추가하는 것이다.
참고로 shift()
메서드는 제일 앞에 요소를 "pop"해가는 것이다.