https://loy124.tistory.com/185
위 코드와 거의 유사하나 EventBus를 활용하여 중앙 통제 함수를 만들어서 활용한다
EventBus는 함수를 중앙통제 관리하고
Vuex는 데이터를 중앙통제 관리하는점이 차이라고 한다
빈 껍데기인 EventBus.js를 만들어준다
import Vue from 'vue';
export default new Vue();
기존의 TdComponent.vue
<template>
<td @click="onClickTd">{{ cellData }}</td>
</template>
<script>
export default {
props: {
cellData: String,
rowIndex: Number,
cellIndex: Number,
},
methods: {
onClickTd() {
//root값의 데이터를 가져온다
// console.log(this.$root.$data);
//부모의 데이터를 가져온다
// console.log(this.$parent.$data);
//자식 컴포넌트에서 부모컴포넌트의 데이터를 변경할 수 있다.
//화면에서 반영이 되지 않는다
//부모의 데이터는 잘 변경이되는데 화면에는 그려지지 않는다
// this.$root.$data.tableData[this.rowIndex][
// this.cellIndex
// ] = this.$root.$data.turn;
//this.$set으로 일치화해주는 작업을 실시한다
// 또한 인덱스를 여러번 쓰는경우 마지막 index를 key로 하면 된다
if (this.cellData) return;
const rootData = this.$root.$data;
this.$set(
rootData.tableData[this.rowIndex],
this.cellIndex,
rootData.turn,
);
let win = false;
if (
rootData.tableData[this.rowIndex][0] === rootData.turn &&
rootData.tableData[this.rowIndex][1] === rootData.turn &&
rootData.tableData[this.rowIndex][2] === rootData.turn
) {
win = true;
}
if (
rootData.tableData[0][this.cellIndex] === rootData.turn &&
rootData.tableData[1][this.cellIndex] === rootData.turn &&
rootData.tableData[2][this.cellIndex] === rootData.turn
) {
win = true;
}
//대각선
if (
rootData.tableData[0][0] === rootData.turn &&
rootData.tableData[1][1] === rootData.turn &&
rootData.tableData[2][2] === rootData.turn
) {
win = true;
}
if (
rootData.tableData[0][2] === rootData.turn &&
rootData.tableData[1][1] === rootData.turn &&
rootData.tableData[2][0] === rootData.turn
) {
win = true;
}
//승리했을때
if (win) {
rootData.winner = rootData.turn;
rootData.turn = 'O';
rootData.tableData = [
['', '', ''],
['', '', ''],
['', '', ''],
];
} else {
//무승부일때
let all = true; //all이 true면 무승부
//무승부 검사
rootData.tableData.forEach(row => {
//2차원 배열이니 두번 forEach 실행
row.forEach(cell => {
// 칸이 비어있는경우면 all = false
if (!cell) {
all = false;
}
});
});
//무승부일때 값 초기화
if (all) {
rootData.winner = '';
rootData.turn = 'O';
rootData.tableData = [
['', '', ''],
['', '', ''],
['', '', ''],
];
//무승부가 아니므로 턴만 넘긴다
} else {
rootData.turn = rootData.turn === 'O' ? 'X' : 'O';
}
}
// console.log(rootData);
},
},
};
</script>
<style></style>
해당부분의 클릭 처리함수를
TicTacToe.vue에 가져온다
TicTacToe.vue(루트부분)
빈껍데기인 EventBus를 import해주고
EventBus.$on('함수이름', 실제로 사용한 함수);
방식으로 활용한다
<template>
<div>
<div>{{ turn }}님의 턴입니다.</div>
<table-component :table-data="tableData"></table-component>
<div v-if="winner">{{ winner }}님의 승리!</div>
</div>
</template>
<script>
import Vue from 'vue';
import TableComponent from './TableComponent';
import EventBus from './EventBus';
export default {
components: {
TableComponent,
},
data() {
return {
tableData: [
['', '', ''],
['', '', ''],
['', '', ''],
],
turn: 'O',
winner: '',
};
},
methods: {
//뷰에서 객체나 배열이 있고 내부의값을 인덱스로 변경하면 화면에 적용되지 않는다
//객체로 key값을 바꾸는경우도 마찬가지
// //push등으로 사용하면 적용이 된다
// onChangeData(){
// this.tableData[0][1] = 'O';
// }
onChangeData() {
//this.tableData[1][0] = 'X' 작동하지 않는다
//Vue를 import하고 바꾸고싶은 값을 Vue.set을 사용한다
// this.tableData[1][0]에 'X'를 넣는다
// Vue.set(this.tableData[1], 0, 'X');
//Vue를 import 안하더라도 해당 방식으로 해결가능하다
// this.$set(this.tableData[1], 0, 'X');
},
onClickTd(rowIndex, cellIndex) {
console.log(rowIndex, cellIndex);
this.$set(this.tableData[rowIndex], cellIndex, this.turn);
let win = false;
if (
this.tableData[rowIndex][0] === this.turn &&
this.tableData[rowIndex][1] === this.turn &&
this.tableData[rowIndex][2] === this.turn
) {
win = true;
}
if (
this.tableData[0][cellIndex] === this.turn &&
this.tableData[1][cellIndex] === this.turn &&
this.tableData[2][cellIndex] === this.turn
) {
win = true;
}
//대각선
if (
this.tableData[0][0] === this.turn &&
this.tableData[1][1] === this.turn &&
this.tableData[2][2] === this.turn
) {
win = true;
}
if (
this.tableData[0][2] === this.turn &&
this.tableData[1][1] === this.turn &&
this.tableData[2][0] === this.turn
) {
win = true;
}
//승리했을때
if (win) {
this.winner = this.turn;
this.turn = 'O';
this.tableData = [
['', '', ''],
['', '', ''],
['', '', ''],
];
} else {
//무승부일때
let all = true; //all이 true면 무승부
//무승부 검사
this.tableData.forEach(row => {
//2차원 배열이니 두번 forEach 실행
row.forEach(cell => {
// 칸이 비어있는경우면 all = false
if (!cell) {
all = false;
}
});
});
//무승부일때 값 초기화
if (all) {
this.winner = '';
this.turn = 'O';
this.tableData = [
['', '', ''],
['', '', ''],
['', '', ''],
];
//무승부가 아니므로 턴만 넘긴다
} else {
this.turn = this.turn === 'O' ? 'X' : 'O';
}
}
},
},
created() {
//사용자 정의 이벤트 등록
EventBus.$on('clickTd', this.onClickTd);
},
};
</script>
<style scoped></style>
변경된 TdComponent.vue
EventBus.$emit('clickTd')를 활용하여 호출을 해준다
<template>
<td @click="onClickTd">{{ cellData }}</td>
</template>
<script>
import EventBus from './EventBus';
export default {
props: {
cellData: String,
rowIndex: Number,
cellIndex: Number,
},
methods: {
onClickTd() {
//root값의 데이터를 가져온다
// console.log(this.$root.$data);
//부모의 데이터를 가져온다
// console.log(this.$parent.$data);
//자식 컴포넌트에서 부모컴포넌트의 데이터를 변경할 수 있다.
//화면에서 반영이 되지 않는다
//부모의 데이터는 잘 변경이되는데 화면에는 그려지지 않는다
// this.$root.$data.tableData[this.rowIndex][
// this.cellIndex
// ] = this.$root.$data.turn;
//this.$set으로 일치화해주는 작업을 실시한다
// 또한 인덱스를 여러번 쓰는경우 마지막 index를 key로 하면 된다
if (this.cellData) return;
//이벤트버스의 $on(this.onclickTd)
EventBus.$emit('clickTd', this.rowIndex, this.cellIndex);
// console.log(rootData);
},
},
};
</script>
<style></style>
중앙처리를 활용해서 쉽게 처리할 수 있으나 중앙코드가 너무 길어지는 단점이있다
'Vue > vue 기초 공부하기' 카테고리의 다른 글
MVVM 모델의 ViewModel에 다해 알아보기 (0) | 2020.03.08 |
---|---|
Vue로 틱택토만들기(Vuex) (0) | 2020.02.22 |
Vue로 틱택토 만들기( $root.data를 활용) (0) | 2020.02.22 |
로또 번호 생성 프로그램 만들기 (props, component 활용) (0) | 2020.01.26 |
Vue 가위바위보 게임 만들기 (vue-LifeCylce 활용) (0) | 2020.01.19 |