0 뷰 원리

source: categories/study/vue-principle/vue-principle_0.md

0.1 강좌 소개 및 맛보기

  • 순수 HTML을 사용해도 Vue를 적용할 수 있다.
  • vue, react 등 SPA(Single Page Application)은 주소가 안 바뀐다. 파일이 말 그대로 하나이기 때문에.
    • 한 개의 페이지에서 컴포넌트를 갈아끼우는 형식으로 동작 (주소 이동은 눈속임)
    • 그래서 vue, react 등 SPA에선 어떤 부분이 바뀌느냐, 그 바뀌는 부분의 데이터를 관리하는 것이 가장 중요하다.


<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <div id="root">
    <div>좋아요 눌렀음</div>
    <button type="button">Like</button>
  </div>
</body>
<script>
const app = new Vue({
  el: '#root',
  data: {
    liked: false,
  },
  methods: {
    onClickButton() {
      this.liked = true;
    }
  }
})
</script>
</html>


  • 데이터 연동만으로 화면 갱신을 자동으로 해준다.
    • 제이쿼리와의 차이점: 제이쿼리는 데이터가 바뀌면 직접 append 해주거나 remove 하거나 처리해야될게 많았다.
  • 프론트앤드, 퍼블리싱할 때 가장 중요한점
    • 데이터와 화면과 일치시켜줘야된다.
    • 이걸 Vue, React 는 어느정도는 대신해주기 때문에 Vue, React 로 개발하면 엄청 편해진다.
  • React 를 하던 Vue 를 하던 데이터 관리가 핵심이다.
  • 사고 방향을 데이터 중심으로 바꿔야된다.

0.2 data 와 v-if, v-else

  • 데이터 중심 사고
    • 화면을 뷰가 데이터에따라 화면을 알아서 갱신해주기 때문


<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <div id="root">
    <div v-if="liked">좋아요 눌렀음</div>
    <button v-else type="button" 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>


0.3 보간법(중괄호 두개 문법)과 v-model

  • 항상 데이터 중심 사고를 해야된다.


<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
  <div>{{ first }}곱하기 {{ second }}는?</div>
  <form>
    <input type="number" v-model="value">
    <button type="submit">입력</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),
    value: '',
    result: '',
  },
  methods: {},
})
</script>
</body>
</html>


0.4 ref 와 구구단 완성하기

  • SPA는 화면을 바꿀 필요가 없다는 것을 인지하셔야됩니다.
    • 아래 처음 페이지에 들어가면 죽을때까지 아래 처음 페이지에서 있는겁니다.
    • 아래 페이지에서 죽을때까지 있는 거고, data만 수정하는 겁니다.
    • ref를 남용하는 것은 안좋습니다. data로 처리하기 애매한 경우에만 사용하도록 합니다.
    • this.$refs.answer.value = '123' 이렇게 하려고할 때가 있는데, 이렇게 하면 절대 안됩니다.
      • 이 경우는 data를 바꾸는 것이 아니라 태그의 값을 직접 바꿔주는 것이기 때문에 화면과 데이터가 불일치하는 현상이 발생하게 된다.
      • 화면과 데이터가 불일치하는 현상이 나오기 때문에 ref를 사용하더라도 왠만하면 화면은 직접 건드리지 않는다.


<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="root">
  <div>{{ first }}곱하기 {{ second }}는?</div>
  <form v-on:submit="onSubmitForm">
    <input type="number" ref="answer" v-model="value">
    <button type="submit">입력</button>
  </form>
  <div id="result">{{ result }}</div>
</div>
<script>
const app = new Vue({
  el: '#root',
  data: {
    first: Math.ceil(Math.random() * 9),
    second: Math.ceil(Math.random() * 9),
    value: '',
    result: '',
  },
  methods: {
    onSubmitForm(e) {
      e.preventDefault(); // 이걸 안하면 페이지가 새로고침된다.
      // vue, react 같은 SPA(single page application)는 페이지 새로고침을 막아야되기 때문에 
      // form 태그가 기본적으로 하는 페이지 새로고침을 막기 위해서 e.preventDefault()를 넣습니다.
      // 아니면 vue modifier를 통해 preventDefault를 구현해도 됩니다. submit.prevent
      if (this.first * this.second === parseInt(this.value)) {
        this.result = '정답';
        this.first = Math.ceil(Math.random() * 9);
        this.second = Math.ceil(Math.random() * 9);
        this.value = '';
        this.$refs.answer.focus();
      } else {
        this.result = '땡';
        this.value = '';
        this.$refs.answer.focus();
      }
    },
  },
})
</script>
</body>
</html>


Note

vue, react의 장점은 언제 부각되느냐.
만들고자 하는 웹 사이트가 어느정도 중에서 대규모가 되었을 때.. 사실 소규모 프로젝트면 잘 체감이 안된다.
규모가 어느정도 커지면 그때서야 편함이 체감이된다.

중~대규모 프로젝트에선 데이터와 화면이 틀어지는 현상이 자주 발생하는데 그것 때문에 엄청 짜증이 발생한다.
코드도 너무 복잡해지고..
그런데 vue, react는 데이터 중심으로 바라보게해줘서 그러한 문제점들을 해결해준다.
화면은 알아서 vue, react가 그려주니까 데이터만 잘 관리해주면 된다는 것이다.

0.5 끝말잇기 만들며 복습

  • data만 생각해라


<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/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>


0.6 Q&A

  • 그러면 화면은 어떻게 바꾸냐. 보통 웹 사이트를 보면 화면은 고정되어있지 않고 계속 바뀐다. 그거는 어떻게 처리?
    • v-if, v-else로 처리하면 된다.
      • 실무에선 v-if, v-else를 막 나열하면서 복잡하게 코드를 짜진 않지만 원리는 같다.
      • 미리 화면을 다 만들어놓고 데이터만 바꿔서 화면에 뿌려준다.
      • vue, react를 하시려면 사고방식을 바꾸셔야된다.
    • 나중에 복잡해지면 router가 들어가고 그러겠지만, 기본적으로 v-if, v-else로 화면이 보였다 안보였다를 통제할 수 있다.
    • v-show라는 뷰 디렉티브 속성도 있다.

  • 모든 페이지를 다 만들었다? 그럼 어떤 문제 발생?
    • 페이지가 너무 무거워진다.
    • 굳이 지금 필요하지도 않은 화면을 vue, react 둘 다 똑같이 다 만들어놓고 있는다.
    • 지금 난 결제 화면에 들어왔는데 vue, react에선 메인화면 어드민 화면 등 모든 화면을 만들어놓고 있는다. 때문에 용량 증가 및 로드 속도 저하.
    • 이런 문제를 해결하기 위해선?
      • 코드 스플리팅
      • SPA는 아예 새로운 개념이라 사고방식이 전환되면서 그에따른 문제가 발생한다. (캐싱이 안된다던가..)
      • 이런 별에별 문제가 발생하면 그걸 해결하는 또 다른 방법을 알아야되고 .. 산 넘어 산..
      • 그래서 배워야될게 끊임없이 나온다. (새로운 패러다임이기 때문에 그렇다고 보시면됨)

  • 여튼 기본 원리는 모든 화면을 다 만들어놓고 데이터를 바꾼다.
  • 데이터를 바꾸면 알아서 화면이 바뀐다.
  • 다음 시간부턴 왜 위와 같이 script 태그에 vue 불러오는 형식으로 개발을 안 하는지 그 이유를 보여드릴 것이다.
    • 웹팩 복잡하고 어려워서 쓰기 싫은데 왜 웹팩을 배우고 쓸 수밖에 없는지, 그 이유에 대해..
    • 왜냐면 웹팩 안 쓴게 더 복잡하다..
    • 그래서 그나마 덜 복잡한 웹팩을 사용하는 것이다. 그냥 개발하면 너무 복잡.