본문 바로가기
Tech/Front End

[Vue공부] 1. 알고 있어야 하는 개념들-2)

by Augustine™ 2021. 10. 28.
반응형

https://augustines.tistory.com/209

 

[Vue공부] 1. 알고 있어야 하는 개념들-1)

Vue.js를 공부하기 전에 MVVM 에 대해 간단히 알아보자. Vue.js에서는 반응형 웹을 지원하기 위해 MVVM(Model-View-ViewModel)을 따른다. 기존 MVC 모델과의 차이점은 ViewModel 도입과 데이터 바인딩에 있다. 아.

augustines.tistory.com

Vue Component 

 Vue에서 계속 나오는 개념 중, 컴포넌트라는 것이 있다. Vue 공식 문서(https://kr.vuejs.org/v2/guide/) 중에는 다음과 같이 정의 하고 있다.

컴포넌트 시스템은 Vue의 또 다른 중요한 개념입니다. 이는 작고 독립적이며 재사용할 수 있는 컴포넌트로 구성된 대규모 애플리케이션을 구축할 수 있게 해주는 추상적 개념입니다. 생각해보면 거의 모든 유형의 애플리케이션 인터페이스를 컴포넌트 트리로 추상화할 수 있습니다.

Vue의 컴포넌트는 기능별로 자바스크립트와 템플릿을 하나의 세트로 묶어서 다른 기능과 분리하여 개발할 수 있도록 해주는 기능이다. Vue에서 컴포넌트는 아래 코드와 같이 Html, Js, Css가 세트로 구성된다.

<template>
  
</template>

<script>
export default {

}
</script>

<style>

</style>

즉, 하나의 기능에만 충실한 컴포넌트 제작이 독립적으로 제작이 가능하다. 이러한 컴포넌트를 조립하여 새로운 페이지를 생산할 수 있고, 또 컴포넌트의 재사용이 가능하여, 효율적으로 웹 페이지 개발을 할 수 있다.

물론 웹 어플리케이션의 기획에 따라, 컴포넌트의 구조가 매우 복잡해질 수 있다. 이런 경우, Vuex를 활용하여 컴포넌트의 구조를 손쉽게 관리할 수 있다. Vuex는 좀 더 뒤에서 다루어 보는 것으로 ...

다시 돌아와서, Vue의 컴포넌트는 새로운 인스턴스를 만드는 것부터 시작한다. 아래 코드와 같이 생성자 함수를 통해 Vue 인스턴스를 생성한다.

var vm = new Vue({
    el: '#app'
})

위 코드를 실행해보면, 브라우저의 개발자 도구에서 인스턴스가 생성된 것을 확인할 수 있다.

 

생성한 인스턴스에서 사용할 컴포넌트를 추가해보자. 일단 CSS는 무시하고, 웹 페이지의 탑 메뉴와 레프트 메뉴가 있다고 가정하자. 우리는 탑메뉴와 레프트 메뉴를 컴포넌트로 만들어 관리할 것이다.

<!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>
  </head>
  <body>
    <div id="app">
      <top-menu></top-menu>
      <left-menu></left-menu>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      var vm = new Vue({
        //options
        el: '#app',
        components: {
          'top-menu': {
            template: '<ul><li>menu1</li><li>menu2</li></ul>',
          },
          'left-menu': {
            template: '<ul><li>left1</li><li>left2</li></ul>',
          },
        },
      })
    </script>
  </body>
</html>

위 코드를 라이브 서버로 확인해서 Vue의 컴포넌트 구조를 확인하면 아래 그림과 같다.

 

전역 컴포넌트 vs 지역 컴포넌트

TopMenu는 웹 페이지에서 전 영역에 걸쳐서 표시되어야 한다. 따라서, TopMenu는 전역 컴포넌트로 등록하자. 

<!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>
  </head>
  <body>
    <div id="app">
      <top-menu></top-menu>
      <left-menu></left-menu>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      //전역 컴포넌트 등록 방식
      Vue.component('top-menu', {
        template: '<ul><li>menu1</li><li>menu2</li></ul>',
      })

      var vm = new Vue({
        //options
        el: '#app',
        components: {
          'left-menu': {
            template: '<ul><li>left1</li><li>left2</li></ul>',
          },
        },
      })
    </script>
  </body>
</html>

전역으로 등록한 top-menu는 별도의 컴포넌트 등록 작업 없이 다른 웹페이지에서도 호출이 가능하다. 즉, 어떤 루트 Vue 인스턴스에서도 사용할 수 있다. 아래 코드처럼 전역 컴포넌트를 등록한 후, 인스턴스에서 별도의 컴포넌트 등록 작업 없이 사용이 가능하다.

Vue.component('comp-a', {/* some code */})
Vue.component('comp-b', {/* some code */})
Vue.component('comp-c', {/* some code */})

new Vue({ el: '#app' })


<div id="app">
	<comp-a></comp-a>
    <comp-b></comp-b>
    <comp-c></comp-c>
</div>

 

지역 컴포넌트는 아래와 같은 형식으로 정의하고 사용할 수 있다.

var compA = { /* some code */ }
var compB = { /* some code */ }
var compC = { /* some code */ }

new Vue({
	el: '#app',
    components: {
    	'comp-a' : compA,
        'comp-b' : compB,
        'comp-c' : compC,
    }
})

다만, 지역 등록된 컴포넌트는 하위 컴포넌트에서 사용이 불가능하다. 

 

Vue Instance 생명 주기

Vue Instance 가 생성되면 생명 주기라는 이벤트를 거친다. 아래 그림을 살펴보자.

Vue Instance Live cycle 출처 : https://kr.vuejs.org/v2/guide/instance.html

  • created : 인스턴스가 생성되고, 리액티브 데이터가 초기화된 직후에 호출된다. 아직 DOM이 구축되지 않은 상태이다. 개인적으로 Vue 코딩할 때, 가장 많이 사용한 이벤트 훅이었다.
  • mounted : 인스턴스의 상태를 사용해서 DOM을 만든 직후에 호출된다. 
  • updated : 데이터가 변경되어 DOM에 적용된 후, 호출된다.
  • destroyed : Vue 인스턴스가 제거된 후, 호출된다.

 

computed 속성

단어 그대로 받아 들이면 별거 아닌데, 이게 참 어렵게 와 닿는다. 계산된 속성이라..

Vue 공식 문서에서는 computed를 연산 결과를 캐싱해주는 역할을 수행한다고 한다. 무슨 말인고 하니.. 아래 코드를 살펴보자.

먼저 App.vue

<template>
  <div id="app">
    <Computed-Test></Computed-Test>
  </div>
</template>

<script>
import ComputedTest from './components/ComputedTest.vue'
export default {
  name: 'App',
  components: {
    ComputedTest,
  },
}
</script>

<style></style>

그리고 ComputedTest.vue

<template>
  <div>
    <h1>{{ computedCalc + this.num }}</h1>
    <h1>{{ methodCalc() + this.num }}</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num: 10,
    }
  },
  computed: {
    computedCalc() {
      return Math.random()
    },
  },
  methods: {
    methodCalc() {
      return Math.random()
    },
  },
}
</script>

ComputedTest.vue 파일을 보면, computed 속성인 computedCalc가 있고, 그냥 method인 methodCalc 가 있다. computed 속성은 연산결과를 캐싱하여 사용할 수 있는 반면, methodCalc는 화면에 랜더링 될 때마다 연산을 수행한다. 즉, 캐싱 이득을 취할 수 없다.

브라우저로 확인해보자. data에 있는 num값을 변경하면 computedCalc와 methodCalc 는 다르게 동작하는 걸 확인할 수 있다. computedCalc는 num 값이 바뀌더라도 캐싱된 Math.random 값을 가져오는 반면, methodCalc는 반복해서 연산을 수행한 다음 랜더링 되는 것을 알 수 있다.

computed에 등록된 함수는 Vue template에서 속성으로 접근할 수 있고, method로 등록된 함수는 함수를 호출하는 방식으로 접근해야 한다. 

 

Watch 속성

watch 속성은 일반적으로 인스턴스의 데이터 변경을 관찰하고 이에 반응하는 기능을 제공한다. 보통 비동기 통신에서 어떤 데이터를 요청 후, 그에 대한 응답의 후처리를 위해 활용할 수 있다.

watch 에 대한 내용은 아래 포스팅을 참조하자.

https://augustines.tistory.com/213

 

[Vue공부] 4. watch를 이용한 데이터 상태 감시

https://augustines.tistory.com/212 [Vue공부] 3. vue 기초문법 https://augustines.tistory.com/211 [Vue공부] 2. Vue-cli 와 설치 https://augustines.tistory.com/209 [Vue공부] 1. 알고 있어야 하는 개념들-1..

augustines.tistory.com

 

반응형

댓글