FrontEnd/Vue를 이용한 웹 게임 만들기

Chapter 01. Vue 환경 설정, 끝말잇기 게임

계란💕 2023. 3. 29. 14:29
  • 순수 html로 Vue 만들어보자
  • 웹팩, 바벨(Babel)이 없어도 html 만으로도 가능하다. 

Vue 환경 설정

 

 

  • VS code를 다운받고 작업하려는 폴더에서 VS code 터미널을 연다. 
    • npm install -g@vue/cli 입력

 

 

  • 다운 완료

 

 

  • 입력해서 로컬에서 실행해준다. 
    • npm run local 

 

 

  • 로컬에서 실행이 되면 다음과 같이 뜬다. 

 

  • 웹 페이지가 뜨면  실행 완료!

 


  • vue 라이브러리를 사용하기 위한  source를 넣는다. 
    • 이 소스를 넣어주면 좋아요 페이지의 <div> 내용을 뷰의 컴포넌트 또는 템플릿으로 전환한다. 
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

 

  • html
<hide/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>구구단</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
</body>
</html>

 

  • 좋아요
    • el 에다가 통제할 대상의 속성 이름인 root를 넣어준다. 
    • Vue가 root 영역을 통제할 수 있도록 한다. 
<hide/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>좋아요</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id = "root">
        <button>Like</button>
    </div>
</body>
<script>
    const app = new Vue({
        el: '#root'
    });
</script>
</html>

 

  Note) 실행 결과


좋아요 버튼 클릭 이벤트

  • Vue나 React 같은 싱글 페이지 애플리케이션(SRP)은 URL이 바뀌지 않는다. 
    • 따라서 이벤트에 대해 preventDefault()를 설정해준다. 
  • 즉, 하나의 페이지 안에서 모든 동작이 이뤄져야한다. 
  • JQuery의 경우에는 데이터가 바뀌면 데이터에 따라 수정된 화면도 필요하다. 
  • 하지만 Vue를 이용하면 데이터가 바뀔 때 Vue가 알아서 수정을 해주기 때문에 간편한다

 

  Ex)

  • 바뀔 부분을 liked = false 이런 식으로 해준다. 
  • 버튼 누르면 liked가 true가 된다. 
  • this는 data 영역을 가리킨다. 
    • this.liked 는 data안에 liked에 대한 부분이다. 
    • 좋아요 누르면 true로 바뀌도록 한다. 
    • data 영역 안에 개발자가 변수를 만든다. 
    • Vue() 안에 el, data, methods 는 고정된 키워드이므로 바꿀 수 없다. 
<hide/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>좋아요</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="root">
        <button>Like</button>
    </div>
</body>
<script>
    const app = new Vue({
        el: '#root',
        data: {
            liked: false

        },
        methods: {
            onClickButton() {
                this.liked = true;
            }
        }
    });
</script>
</html>

  Note) 

  • id가 'root'인 영역에 대해 Vue가 통제하고 있다. 
  • 이제 vue 관련된 기능을 연결할 수 있다.

 

  • 좋아요 버튼 누르면 버튼이 사라지고 "좋아요 눌렀음" 을 표시해보자.
    • 버튼 눌렀을 때, 메서드가 실행되도록 한다. 
    • html에서는 onclick인 것과 다르게 Vue에서는 v-on:click를 이용한다. → Vue가 통제하는 메서드가 연결된다. 
    • 둘 중 하나는 항상 숨기도록 v-if를 사용한다. 
    • cf) 'v-'를 붙이면 따옴표 안에는 JavaScript 관련한 데이터나 메서드에 접근할 수 있다. 
      • v-on: 클릭 이벤트를 달아준다. 
      • v-if: liked가 true인 경우 표시되는 영역
      • v-else: liked가 false인 경우 보여지는 영역으로 v-else-if를 여러 개 만들 수도 있음.
      • 조건문과 비슷하다. v-if, v-else는 동등한 형제면 적용 받는다.
      • 형제끼리는 인접하게 붙여서 쓴다. 
<hide/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>좋아요</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="root">
        <div v-if="liked">좋아요 눌렀음</div>
        <button v-else v-on:click="onClickButton">
            Like
        </button>
    </div>
</body>
<script>
    const app = new Vue({
        el: '#root',
        data: {
            liked: false
        },
        methods: {
            onClickButton() {
                this.liked = true;
            }
        }
    });
</script>
</html>

 

  Note) 실행 결과

  • Vue가 root 태그 영역을 관리하면서 자동으로 관리해준다. 
  • Vue가 관리하니까 기존의 html 은 잠시 잊자!
    • 데이터만 개발자가 관리하면 화면은 Vue가 알아서 관리해준다. 

누르기 전
누른 다음

 


보간법과 v-model

  • 보간법: 빠진 값을 측정하기 위해 해당 점과 인접한 두 포인트 를 사용해서 값을 예측하는 방법을 말한다. 
    • 보간법은 일부 데이터 포인트가 주어진 경우 그 사이 값을 예측하는 것이 목표이다. 

 

 

  Ex) Math 라이브러리에서 두 개의 랜덤값 보여주기

  • 바뀌는 부분이 <script> 영역 안에서 data에 해당한다. 
  • html 속성 안에서는 "중괄호 두 개"를 겹치면 그 안에 데이터를 가져와서 렌더링(화면에 표시)할 수 있다 .
  • <script> 안에서는 "this."을 붙여서 데이터에 접근한다. 
<hide/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>구구단</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="root">
        <div>{{first}} X {{second}}는?</div>
        <form>
            <input type="number">
            <button>입력</button>
        </form>
        <div id="result"></div>
    </div>
    <script>
        const app = new Vue({
            el: '#root',
            data: {
                first: Math.ceil(Math.random() * 9),
                second: Math.ceil(Math.random() * 9),
                result: '',
                value: ''
            },
            methods: {
                a() {
                    this.first
                }
            }
        });
    </script>
</body>
</html>

  Note) 실행 결과

  • <body>안에 <script> 영역이 들어가야한다. 
  • 입력 버튼을 누를 때마다 first, second 값이 바뀌는데 이 부분은 Vue가 컨트롤 중인 게 아니라 입력을 누를 때마다 화면이 새로고침 되고 있는 중이라서 그렇다. 
    • form의 기본 특성이 클릭할 때마다 새로고침이 되는 것이다. 
  • cf) React는 state를 선언하는데 Vue는 data{}를 선언한다. 

 

 

 

  Ex)  Input 태그에 들어오는 값을 data 에서도 쓰려면?

  • v-model 을 이용해서 다음과 같이 data 값과 연결해준다. 
  • userInput이라는 변수를 만들어서 시험 삼아 콘솔에 출력해보자
    •             <div>{{userInput}}</div> 
    • 위 코드를 추가해본다. 
<hide/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>구구단</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="root">
        <div>{{first}} X {{second}}는?</div>
        <form>
            <input type="number" v-model="userInput">
            <button>입력</button>
            <div>{{userInput}}</div>
        </form>
        <div id="result"></div>
    </div>
    <script>
        const app = new Vue({
            el: '#root',
            data: {
                first: Math.ceil(Math.random() * 9),
                second: Math.ceil(Math.random() * 9),
                userInput: '',
                result: ''
                
            },
            methods: {
                a() {
                    this.first
                }
            }
        });
    </script>
</body>
</html>

 

  Note) 실행 결과

  • 다음과 같이 userInput에 값이 잘 들어가고 있다. 
  • 입력하는 값이 v-model을 통해 data 영역에 value에도 영향을 준다. 
  • Vue는 이런 양방향 바인딩이 편리하다. 


ref와  구구단 완성하기

 

  Ex)

  • submit 버튼을 누르면 
  • form은 click보다는 submit 이벤트를 주로 쓴다. 
  • 정답을 맞춘 다음에 다른 문제가 나오도록 하려면?
  • 화면은 바꾼 필요 없다는 것을 기억한다! 데이터만 수정한다!
  • Javscript 안에 제출 버튼을 눌렀을 때 실행되는 다음 메서드를 바꿔준다. 
    • "정답"을 보여줌과 동시에 first, second 값을 바로 바꿔준다. 
    • 정답을 맞췄을 때도 input란을 비워준다. 
<hide/>
onSubmitForm(e) {
    e.preventDefault();
    console.log(this);

    if (this.first * this.second === parseInt(this.userInput)) {
        this.result = '정답';
        this.first =  Math.ceil(Math.random() * 9),
        this.second =  Math.ceil(Math.random() * 9),
        this.userInput = '';
    } else {
        this.result = '땡';
    }
}

 

  

 

  Ex) 포커스 자동화 - ref

  • 입력 버튼을 누르면 커서가 입력 창에서 사라진다. 
  • 그런데 입력 버튼을 눌러도 이 커서를 입력 창에 유지시키려면??
  •  ref 라는 속성을 이용한다. 
  • 다음과 같이 인풋에 "answer"라는 이름을 붙여준다. 
  • 주의) ref를 남용하는 것은 좋지 않고 어쩔 수 없는 상황에서만 쓰도록 한다. 

 

  • 인풋 칸을 answer 라고 이름지어준다. 
<input type="number" ref = "answer" v-model="userInput">

 

  • this.$refs.answer.focus();
    • 위에서 answer라고 이름 붙인 부분, 즉 입력 칸 부분에 커서가 깜빡이도록 focus()를 설정해준다. 
<hide/>
if (this.first * this.second === parseInt(this.userInput)) {
    this.result = '정답';
    this.first =  Math.ceil(Math.random() * 9),
    this.second =  Math.ceil(Math.random() * 9), 
    this.userInput = '';
    this.$refs.answer.focus();
}

끝말잇기 만들기

  • 데이터가 바뀌는 영역의 개수를 센다. 그 개수가 data 영역의 변수 개수이다. 

 

  Ex) 

  • word(제시어)의 마지막 글자와 value(입력 값)의 첫 글자가 같으면 끝말잇기 정답이다. 
<hide/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="root">
        <div>{{word}}</div>
        <form v-on:submit="onSubmitForm">
            <input type="text" v-model="value">
            <button type="submit">입력!</button>
        </form>
        <div>{{result}}</div>
    </div>
    <script>
        const app = new Vue({
            el: '#root',
            data: {
                word: '제로초',
                result: '',
                value: ''
            },
            methods: {
                onSubmitForm(e) {
                    e.preventDefault();
                    if (this.word[this.word.length - 1] === this.value[0]) {
                        this.result = "딩동댕";
                    } else {
                        this.result = "땡";
                    }
                }
            }
        })
    </script>
</body>
</html>

  Note) 실행 결과

  • 맞추고 나면 정답이 제시어 자리로 넘어가도록 설정한다. 
  • 입력 버튼을 누르고나면 입력 칸이 비워지도록 다음과 같이 설정한다. 
  • 아까와 마찬가지로 입력 버튼을 누른 후에도 입력 칸에 커서가 유지되도록 focus를 설정한다.
  • 화면은 처음에 만들고 항상 데이터 중심으로 구조를 짠다. 
<hide/>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
    <div id="root">
        <div>{{word}}</div>
        <form v-on:submit="onSubmitForm">
            <input type="text" ref="answer" v-model="value">
            <button type="submit">입력!</button>
        </form>
        <div>{{result}}</div>
    </div>
    <script>
        const app = new Vue({
            el: '#root',
            data: {
                word: '제로초',
                result: '',
                value: ''
            },
            methods: {
                onSubmitForm(e) {
                    e.preventDefault();
                    if (this.word[this.word.length - 1] === this.value[0]) {
                        this.result = "딩동댕";
                        this.word = this.value;
                        this.value = '';
                        this.$refs.answer.focus();
                    } else {
                        this.result = "땡";
                        this.value = '';
                        this.$refs.answer.focus();
                    }
                }
            }
        })
    </script>
</body>
</html>

Note

  • 화면이 보이거나 안 보이거나 통제: v-if, v-else, v-show
    • 모든 화면을 먼저 만든 다음에 위 키워드로 관리한다. 
    • ex) main이나 sub같은 화면을 먼저 만든 다음에 ,<div v-else-if ="route ==='sub'"> ..같은 형식으로 화면을 바꿀 수 있다. 

 

찾아보기

  • 웹팩(WebPack)이란?
    • 프론트엔드 프레임워크에서 가장 많이 사용되는 모듈 번들러(Module Bundler)이다. 
    • 모듈 번들러(Module Bundler): 웹 애플리케이션을 구성하는 자원을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구를 말한다. 
  • 바벨(Babel)이란?
    • 자바스크립트 컴파일러이다. 최신 자바스크립트 문법을 사용 가능하다. 

 

 

cf) 웹팩 참고 링크

https://joshua1988.github.io/webpack-guide/webpack/what-is-webpack.html#%EB%AA%A8%EB%93%88%EC%9D%B4%EB%9E%80

 

 

출처 

웹 게임을 만들며 배우는 vue 

https://www.inflearn.com/course/lecture?courseSlug=web-game-vue&unitId=23120