# 시작하기

NOTE

이미 Vue 2를 알고 있고 Vue 3의 새로운 점을 배우고 싶으신가요? Migration Guide를 확인하세요!

# Vue.js가 무엇인가요?

Vue(/vjuː/ 로 발음, view 와 발음이 같습니다.)는 사용자 인터페이스를 만들기 위한 프로그레시브 프레임워크 입니다. 다른 단일형 프레임워크와 달리 Vue는 점진적으로 채택할 수 있도록 설계하였습니다. 핵심 라이브러리는 뷰 레이어만 초점을 맞추어 다른 라이브러리나 기존 프로젝트와의 통합이 매우 쉽습니다. 그리고 Vue는 현대적 도구지원 라이브러리 (opens new window) 와 함께 사용한다면 정교한 단일 페이지 응용프로그램을 완벽하게 지원할 수 있습니다.

vue에 대해 깊게 들어가기전에, 여러분에게 주요 원칙과 샘플을 제공하는 비디오를 만들었으니 한번 보시기 바랍니다.

Watch a free video course on Vue Mastery

# 시작하기

설치

TIP

공식 가이드는 HTML, CSS 및 JavaScript에 대한 중간 수준의 지식을 전제로 하고 있습니다. 이제 막 프론트 엔드 개발에 대해 배우기 시작했다면 첫 번째 단계로 프레임워크를 시작하는 것은 좋은 생각이 아닙니다. 기본을 파악한 다음 다시 해보세요! 다른 프레임워크에 대한 사전 경험이 도움될 수 있지만 반드시 필요한것은 아닙니다.

Vue.js를 사용해 볼 수 있는 가장 쉬운 방법은 Hello World 예제 (opens new window)를 사용하는 것입니다. 브라우저의 새 탭에서 열어 본 후 몇 가지 기본 예제를 따라가십시오.

설치 페이지에는 Vue를 설치하기 위한 옵션이 추가로 제공됩니다. 특히 Node.js 기반 빌드 도구에 아직 익숙하지 않으면 vue-cli 로 시작하는 것을 권장하지 않습니다.

# 선언적 렌더링(Declarative Rendering)

Vue.js의 핵심에는 간단한 템플릿 구문을 사용하여 DOM에서 데이터를 선언적으로 렌더링 할 수있는 시스템이 있습니다.

<div id="counter">
  Counter: {{ counter }}
</div>
1
2
3
const Counter = {
  data() {
    return {
      counter: 0
    }
  }
}

Vue.createApp(Counter).mount('#counter')
1
2
3
4
5
6
7
8
9

첫 Vue app을 만들었습니다! 이것은 문자열 템플릿을 렌더링하는 것과 매우 유사하지만, Vue.JS 내부에서는 더 많은 작업을 하고 있습니다. 이제 데이터와 DOM이 연결되었으며 모든 것이 반응형(reactive) 이 되었습니다. 우리는 그것을 어떻게 확인할 수 있을까요? 아래 예제 코드에서 counter 속성은 매 초마다 증가하고 우리는 DOM이 변경될때 어떻게 렌더 되는지 볼 수 있습니다.








 
 
 



const CounterApp = {
  data() {
    return {
      counter: 0
    }
  },
  mounted() {
    setInterval(() => {
      this.counter++
    }, 1000)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

Counter: 0

텍스트 보간 이외에도 다음과 같은 엘리먼트 속성을 바인딩할 수 있습니다.

<div id="bind-attribute">
  <span v-bind:title="message">
    여기에 마우스를 올려두고 잠시 기다리면 제목이 동적으로 바뀝니다!
  </span>
</div>
1
2
3
4
5
const AttributeBinding = {
  data() {
    return {
      message: '이 페이지를 다음 시간에 열었습니다. ' + new Date().toLocaleString()
    }
  }
}

Vue.createApp(AttributeBinding).mount('#bind-attribute')
1
2
3
4
5
6
7
8
9

See the Pen Attribute dynamic binding by Vue (@Vue) on CodePen.

여기서 우리는 새로운 것을 만났습니다. v-bind 속성은 디렉티브 이라고 합니다. 디렉티브는 Vue에서 제공하는 특수 속성임을 나타내는 v- 접두어가 붙어있으며 사용자가 짐작할 수 있듯 렌더링 된 DOM에 특수한 반응형 동작을 합니다. 기본적으로 “이 요소의 title 속성을 Vue 인스턴스의 message 프로퍼티로 최신 상태를 유지 합니다.”

# 사용자 입력 핸들링

사용자가 앱과 상호 작용할 수 있게 하기 위해 우리는 v-on 디렉티브를 사용하여 Vue 인스턴스에서 메소드를 호출하는 이벤트 리스너를 추가 할 수 있습니다 :

<div id="event-handling">
  <p>{{ message }}</p>
  <button v-on:click="reverseMessage">Reverse Message</button>
</div>
1
2
3
4
const EventHandling = {
  data() {
    return {
      message: 'Hello Vue.js!'
    }
  },
  methods: {
    reverseMessage() {
      this.message = this.message
        .split('')
        .reverse()
        .join('')
    }
  }
}

Vue.createApp(EventHandling).mount('#event-handling')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

See the Pen Event handling by Vue (@Vue) on CodePen.

이 방법은 직접적으로 DOM을 건드리지 않고 앱의 상태만을 업데이트합니다. 모든 DOM 조작은 Vue에 의해 처리되며 작성한 코드는 기본 로직에만 초점을 맞춥니다.

Vue는 또한 양식에 대한 입력과 앱 상태를 양방향으로 바인딩하는v-model 디렉티브를 제공합니다.

<div id="two-way-binding">
  <p>{{ message }}</p>
  <input v-model="message" />
</div>
1
2
3
4
const TwoWayBinding = {
  data() {
    return {
      message: 'Hello Vue!'
    }
  }
}

Vue.createApp(TwoWayBinding).mount('#two-way-binding')
1
2
3
4
5
6
7
8
9

See the Pen Two-way binding by Vue (@Vue) on CodePen.

# 조건문과 반복문

엘리먼트가 표시되는지에 대한 여부를 제어하는 것은 아주 간단합니다.

<div id="conditional-rendering">
  <span v-if="seen">이제 나를 볼수 있어요</span>
</div>
1
2
3
const ConditionalRendering = {
  data() {
    return {
      seen: true
    }
  }
}

Vue.createApp(ConditionalRendering).mount('#conditional-rendering')
1
2
3
4
5
6
7
8
9

이 예제는 텍스트와 속성뿐 아니라 DOM의 구조 에도 데이터를 바인딩 할 수 있음을 보여줍니다. 또한 Vue 엘리먼트가 Vue에 삽입/업데이트/제거될 때 자동으로 전환 효과(transition effects) 를 적용되는 강력한 전환 효과 시스템을 제공합니다.

우리는 효과를 확인하기 위해서 위 코드 블록의 seentrue에서 false로 바꿀 수 있습니다.

See the Pen Conditional rendering by Vue (@Vue) on CodePen.

Vue에서 제공하는 특별한 기능을 제공하는 디렉티브들이 있습니다. 예를 들어 v-for 디렉티브는 배열에서 데이터를 가져와 아이템 목록을 표시하는데 사용할수 있습니다.

<div id="list-rendering">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>
1
2
3
4
5
6
7
const ListRendering = {
  data() {
    return {
      todos: [
        { text: 'Learn JavaScript' },
        { text: 'Learn Vue' },
        { text: 'Build something awesome' }
      ]
    }
  }
}

Vue.createApp(ListRendering).mount('#list-rendering')
1
2
3
4
5
6
7
8
9
10
11
12
13

See the Pen List rendering by Vue (@Vue) on CodePen.

# 컴포넌트로 조립하기

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

컴포넌트 트리

Vue에서 컴포넌트는 미리 정의된 옵션을 가진 Vue 인스턴스 입니다. Vue에서 컴포넌트를 등록하는 방법은 간단합니다. App 객체에서 했던 것처럼 우리는 컴포넌트 객체를 만들고 부모 컴포넌트의 components (마지막 복수형에 주의) 옵션에 정의할 수 있습니다.

// 뷰 어플리케이션을 생성합니다.
const app = Vue.createApp(...)

// todo-item 란 이름의 새로운 컴포넌트를 선언합니다.
app.component('todo-item', {
  template: `<li>할일이 있어요</li>`
})

// 어플리케이션을 마운트 합니다.
app.mount(...)
1
2
3
4
5
6
7
8
9
10

이제 다른 컴포넌트의 템플릿에서 이 컴포넌트을 이용해 조립할수 있습니다.

<ol>
  <!-- todo-item 컴포넌트의 인스턴스를 만듭니다.  -->
  <todo-item></todo-item>
</ol>
1
2
3
4

그러나 이것은 todo-item 컴포넌트를 사용할 때마다 똑같은 텍스트를 렌더링할뿐 무언가가 부족합니다. 부모 영역의 데이터를 자식 컴포넌트에 전달할 수 있어야 합니다. prop 을 전달받을 수 있도록 todo-item 컴포넌트의 정의를 수정해봅시다.

app.component('todo-item', {
  props: ['todo'],
  template: `<li>{{ todo.text }}</li>`
})
1
2
3
4

이제 v-bind 를 사용하여 할일을 개별 todo-item 컴포넌트에 전달할 수 있습니다.

<div id="todo-list-app">
  <ol>
    <!--
      이제 할일 todo-item 에 할일을 전달합니다.
      콘텐츠는 동적으로 포현됩니다.
      여기에서 "key"를 또 전달하고 있는데
      이것에 대해서는 나중에 설명하겠습니다.
    -->
    <todo-item
      v-for="item in groceryList"
      v-bind:todo="item"
      v-bind:key="item.id"
    ></todo-item>
  </ol>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const TodoList = {
  data() {
    return {
      groceryList: [
        { id: 0, text: '야채' },
        { id: 1, text: '치즈' },
        { id: 2, text: '사람이 먹을수 있는거라면 뭐든지' }
      ]
    }
  }
}

const app = Vue.createApp(TodoList)

app.component('todo-item', {
  props: ['todo'],
  template: `<li>{{ todo.text }}</li>`
})

app.mount('#todo-list-app')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

See the Pen Intro-Components-1 by Vue (@Vue) on CodePen.

이것은 인위적으로 만든 예시이지만, 우리는 앱을 두 개의 더 작은 단위로 나눌 수 있었고, 자식을 props 인터페이스를 통하여 부모로부터 합리적인 수준으로 분리할 수 있었습니다. 이제 앞으로는 부모 앱에 영향을 주지 않으면서 <todo-item> 컴포넌트를 더 복잡한 템플릿과 로직으로 더욱 향상시킬 수 있을 것입니다.

대규모 애플리케이션에서는 개발을 보다 쉽게 관리 할 수 있도록 전체 앱을 컴포넌트로 나누는 것이 필수적입니다. 나중에 나올 가이드 에서 컴포넌트에 대해 자세히 설명하겠지만 여기서는 컴포넌트를 사용한 앱의 모습이 어떻게 구성될지에 대한 (가상의) 예를 작성하겠습니다.

<div id="app">
  <app-nav></app-nav>
  <app-view>
    <app-sidebar></app-sidebar>
    <app-content></app-content>
  </app-view>
</div>
1
2
3
4
5
6
7

# 사용자 정의 엘리먼트와의 관계

Vue 컴포넌트는 Web Components 표준 (opens new window) 의 일부인 Custom Elements 와 매우 유사하다는 것을 눈치 챘을 수 있습니다. Vue의 컴포넌트 구문은 스펙 이후 느슨하게 모델링 되었기 때문입니다. 예를 들어 Vue 컴포넌트는 Slot API (opens new window)is 특수 속성을 구현합니다. 그러나 몇가지 중요한 차이가 있습니다.

  1. Web Components Spec은 최종안이 정해졌지만 모든 브라우저들이 기본적으로 구현되는 것은 아닙니다. 현재 사파리 10.1+, 크롬 54+ 그리고 파이어폭스 63+ 기본적으로 Web Components를 지원합니다. 이에 비해 Vue 컴포넌트는 지원되는 모든 브라우저 (IE11과 호환되거나 그 이상버젼)에서 일관되게 작동합니다. 필요한 경우 Vue 컴포넌트는 기본 사용자 정의 엘리먼트 내에 래핑할 수 있습니다

  2. Vue 컴포넌트는 컴포넌트간 데이터의 흐름을 비롯해, 사용자 정의 이벤트와 통신, 빌드 도구와의 통합 등 기본 사용자 지정 엘리먼트에서 사용할 수 없었던 중요한 기능을 제공합니다.

Vue는 내부적으로 사용자 정의 엘리먼트를 사용하지 않지만, 사용자 정의 엘리먼트로 사용 또는 배포하는 경우에는 뛰어난 상호운영성 (opens new window) 을 가집니다. Vue CLI는 자기자신을 네이티브 커스텀 엘리먼트로서 등록하는 Vue 컴포넌트의 빌드도 지원하고 있습니다.

# 더 하실 준비가 되셨나요?

우리는 Vue.js 코어의 가장 기본적인 기능을 간략하게 소개했습니다. 이 가이드의 나머지 부분에서 더 자세한 세부 내용이 포함된 다른 고급 기능에 대해 다룰 예정이므로 꼭 읽어보시기 바랍니다.

Deployed on Netlify.
Last updated: 12/20/2020, 2:33:30 PM