Intro to Vue.js

What, Why, and How

1. What is Vue.js?

a progressive framework for building user interfaces

1. Front End

2. SPA (Single Page Application)

  • 단일 νŽ˜μ΄μ§€λ‘œ κ΅¬μ„±λœ μ›Ή μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜

  • 화면이동 μ‹œμ— ν•„μš”ν•œ 데이터λ₯Ό μ„œλ²„μ‚¬μ΄λ“œμ—μ„œ HTML으둜 전달받지 μ•Šκ³ (μ„œλ²„μ‚¬μ΄λ“œ λ Œλ”λ§ X), ν•„μš”ν•œ λ°μ΄ν„°λ§Œ μ„œλ²„λ‘œλΆ€ν„° JSON으둜 전달 λ°›μ•„ λ™μ μœΌλ‘œ λ Œλ”λ§

    • client side rendering!

  • λͺ¨λ“  HTML을 ν΄λΌμ΄μ–ΈνŠΈκ°€ κ°–κ³  있고 μ„œλ²„μ‚¬μ΄λ“œμ—λŠ” ν•„μš”ν•œ 데이터λ₯Ό μš”μ²­ν•˜κ³  JSON으둜 λ°›κΈ° λ•Œλ¬Έμ— 기쑴의 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ— λΉ„ν•΄ 화면을 κ΅¬μ„±ν•˜λŠ” 속도가 λΉ λ₯΄λ‹€

  • μž₯점

    • ν•˜λ‚˜ν•˜λ‚˜ ν™”λ©΄ 전체λ₯Ό λ Œλ”λ§ν•  ν•„μš”κ°€ μ—†κΈ° λ•Œλ¬Έμ— 화면이동이 λΉ λ₯΄λ‹€.

    • 화면에 ν•„μš”ν•œ λΆ€λΆ„μ˜ λ°μ΄ν„°λ§Œ λ°›μ•„μ„œ λ Œλ”λ§ ν•˜κΈ° λ•Œλ¬Έμ— μ²˜λ¦¬κ³Όμ •μ΄ νš¨μœ¨μ μ΄λ‹€.

    • μœ μ €μ— μž…μž₯ν•΄μ„œ μ‚¬μš©ν•˜κΈ° νŽΈλ¦¬ν•˜λ‹€.

  • 단점

    • 처음 화면을 λ‘œλ”©ν•  λ•Œ, λͺ¨λ“  화면이 미리 μ€€λΉ„λ˜μ–΄ μžˆμ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— λ‘œλ”©μ— μ‹œκ°„μ΄ κ±Έλ¦°λ‹€.

    • μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ΅¬ν˜„ν•˜λŠ”λ° 보닀 μ‹œκ°„μ΄ 걸리며 λ³΅μž‘ν•˜λ‹€.

      μ°Έκ³ : https://velog.io/@josworks27/SPA-%EA%B0%9C%EB%85%90

3. Client Side Rendering

image-20200525101243092

4. MVVN (Model View ViewModel) Pattern

image-20200525101419720
  • ꡬ쑰

    • Model

      • μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ‚¬μš©λ˜λŠ” 데이터와 κ·Έ 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” λΆ€λΆ„

    • View

      • μ‚¬μš©μžμ—μ„œ λ³΄μ—¬μ§€λŠ” UI λΆ€λΆ„μž…λ‹ˆλ‹€.

    • View Model

      • Viewλ₯Ό ν‘œν˜„ν•˜κΈ° μœ„ν•΄ λ§Œλ“  Viewλ₯Ό μœ„ν•œ Model

      • Viewλ₯Ό λ‚˜νƒ€λ‚΄ μ£ΌκΈ° μœ„ν•œ Model이자 Viewλ₯Ό λ‚˜νƒ€λ‚΄κΈ° μœ„ν•œ 데이터 처리λ₯Ό ν•˜λŠ” λΆ€λΆ„

  • λ™μž‘ μˆœμ„œ

    • μ‚¬μš©μžμ˜ Action듀은 Viewλ₯Ό 톡해 λ“€μ–΄μ˜€κ²Œ 됨

    • View에 Action이 λ“€μ–΄μ˜€λ©΄, Command νŒ¨ν„΄μœΌλ‘œ View Model에 Action을 전달

    • View Model은 Modelμ—κ²Œ 데이터λ₯Ό μš”μ²­

    • Model은 View Modelμ—κ²Œ μš”μ²­λ°›μ€ 데이터λ₯Ό 응닡

    • View Model은 응닡 받은 데이터λ₯Ό κ°€κ³΅ν•˜μ—¬ μ €μž₯

    • ViewλŠ” View Modelκ³Ό Data Bindingν•˜μ—¬ 화면을 λ‚˜νƒ€λƒ„

  • μž₯점

    • MVVM νŒ¨ν„΄μ€ View와 Model μ‚¬μ΄μ˜ μ˜μ‘΄μ„±μ΄ μ—†λ‹€

    • λ˜ν•œ Command νŒ¨ν„΄κ³Ό Data Binding을 μ‚¬μš©ν•˜μ—¬ View와 View Model μ‚¬μ΄μ˜ μ˜μ‘΄μ„± λ˜ν•œ μ—†μ•€ λ””μžμΈνŒ¨ν„΄

    • 각각의 뢀뢄은 독립적이기 λ•Œλ¬Έμ— λͺ¨λ“ˆν™” ν•˜μ—¬ κ°œλ°œν•  수 있음

      좜처: https://beomy.tistory.com/43 [beomy]

  • Vue.js λŠ” MVVM νŒ¨ν„΄μ˜ ViewModel λ ˆμ΄μ–΄μ— ν•΄λ‹Ήν•˜λŠ” View 단 λΌμ΄λΈŒλŸ¬λ¦¬μ΄λ‹€

5. λ°˜μ‘ν˜• (Reactive)

Vue vs React

곡톡점

  • 가상 DOM을 ν™œμš©

  • λ°˜μ‘μ μ΄κ³  μ‘°ν•© κ°€λŠ₯ν•œ component 제곡

  • core libraryμ—λ§Œ μ§‘μ€‘ν•˜κ³  있고 routing 및 μ „μ—­ μƒνƒœλ₯Ό κ΄€λ¦¬ν•˜λŠ” companion libraryκ°€ 있음

+

Vue.js 와 λ‹€λ₯Έ ν”„λ ˆμž„μ›Œν¬μ™€μ˜ 비ꡐ

https://kr.vuejs.org/v2/guide/comparison.html

2. Why Vue.js?

  1. 배우기 쉽닀!

  2. $ (μ ˆμ•½)

    • Client Side Rendering

  3. UX ν–₯상

    • 비동기 / SPA

  4. ν”„λ ˆμž„μ›Œν¬ (ν”„λ Œμ²΄μ΄μ¦ˆ)의 μž₯점 (DX ν–₯상 - 개발자 κ²½ν—˜ ν–₯상)

    • No etc, 선택과 집쀑

    • μœ μ§€/보수 용이

    • Community와 library

3. How?

Setups

  • VS Code

    • Vetur μ„€μΉ˜

  • Chrome Web Store

    • Vue.js devtools

      • λ°‘μ˜ 두 κ°€μ§€ μ„ νƒν•˜κΈ°

      image-20200525103628912
  • CDN

    • (μ§€κΈˆμ€) μœ„μ˜ 개발 version μ‚¬μš©ν•˜κΈ°


<br>

<br>

### Docs

https://kr.vuejs.org/v2/guide/index.html

- 정말 잘 μ •λ¦¬λ˜μ–΄ μžˆλ‹€! 따라해보며 읡히기!

<br>

<br>

## 4. Getting started with Vue.js 

<br>

### 4-0. `el` attribute

- Vue instance μ•ˆμ— `el` 속성을 톡해 Vue instanceκ°€ 그렀질 지점을 μ§€μ •

ex)

> 00_el.html

```html
<body>
  <div id="app">

  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
      // el은 Vue instance의 속성이닀
      const app = new Vue({
          el: '#app', // μ–΄λ–€ μš”μ†Œμ— mount ν•  μ§€ κ²°μ •ν•˜λŠ” ꡬ간
      })
      console.log(app)
      console.log(app.$el)
  </script>
</body>

4-1. data attribute

  • 화면에 λ³΄μ—¬μ§ˆ 데이터λ₯Ό μ •μ˜

ex)

01_data.html

<body>
    <div id="app">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            // Dataλ₯Ό μ„ μ–Έν•˜λŠ” 방법
            data: { // MVVM 의 Model을 λ‹΄λ‹Ήν•˜λŠ” ꡬ간
                message:'Hello Vue!'
            }
        })
        console.log(app.message) 
    </script>
</body>

4-2. Interpolation

ex)

02_interpolation.html

<body>
    {{ message }}
    <div id="app">
        {{ message }}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data: {
                message:'Hello Vue!'
            }
        })
        console.log(app.message) 
    </script>
</body>

4-3. v-text

  • Vannila JS의 DomElement.innertext와 κ°™μŒ

  • v- μ ‘λ‘μ‚¬λ‘œ μ‹œμž‘ν•˜λŠ” 것듀을 λͺ¨λ‘ directive(λͺ…λ Ή)라고 λΆ€λ₯Έλ‹€

ex)

03_v-text.html

<div id="app">
        <p v-text="message"></p>
        <p> {{message}}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data: {
                message:'μ™„μ „νžˆ κ°™μ•„μš”!'
            }
        })
        console.log(app.message) 
    </script>
</body>

4-4. v-if

  • if ν‰κ°€μ—μ„œ false이면 화면에 λ‚˜μ˜€μ§€ μ•ŠλŠ”λ‹€

ex)

04_v-if.html

<body>
    <div id="app">
        <p v-if="bool1">
            true
        </p>
        <p v-if="bool2">
            false
        </p>

        <p v-if="str1">
            'Yes'
        </p>
        <p v-if="str2">
            ''
        </p>

        <p v-if="num1">
            1
        </p>
        <p v-if="num2">
            0
        </p>

        <!-- JavaScript λŠ” empty array도 true-->
        <p v-if="arr">
            [] => jsλŠ” 빈 배열이 true 평가
        </p>
        <p v-if="arr.length">
            [].lengthλ₯Ό 톡해 0μΈμ§€λ‘œ 확인
        </p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data: {
                bool1: true,
                bool2: false,
                str1: 'Yes',
                str2: '',
                num1: 1,
                num2: 0,
                arr: [],
            }
        })
        console.log(app.message) 
    </script>
</body>

4-5. v-if, v-else-if, v-else

ex)

05_v-if-elseif-else.html

<body>
    <div id="app">
        <p v-if="username === 'master'">
            Hello Master
        </p>
        <p v-else>
            Hello User
        </p>

        <p v-if="number > 0">
            μ–‘μˆ˜
        </p>
        <p v-else-if="number < 0">
            음수
        </p>
        <p v-else>
            0
        </p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data: {
             username: 'master',
             number: 0,
            }
        })
    </script>
</body>

4-6. v-for

ex)

06_v-for.html

<body>
    <div id="app">
        <ul>
            <li v-for="number in numbers">{{ number +1 }}</li>
        </ul>

        <ol>
            <li v-for="teacher in teachers"> {{ teacher.name }}</li>
        </ol>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data: { 
                numbers: [0,1,2,3,4,5],
                teachers: [
                    { name: 'neo'},
                    { name: 'tak'},
                ],
            }
        })
    </script>
</body>

4-7. v-bind

  • ν‘œμ€€ HTML 속성과 Vue Instanceλ₯Ό 연동할 λ•Œ μ‚¬μš© (+ a)

  • v-bind: λ₯Ό μ€„μ—¬μ„œ : 으둜 μ“Έ 수 μžˆλ‹€!

ex)

07_v-bind.html

<body>
    <div id="app">
        <a href=" {{ googleUrl }}">Bad Google link</a>
        <a v-bind:href="googleUrl">Good Google link</a>
        <a :href="naverUrl">Naver link</a>
        <img :src="randomImageUrl" v-bind:alt="altText">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data: { 
                googleUrl: 'https://google.com',
                naverUrl: 'https://naver.com',
                randomImageUrl: 'https://picsum.photos/200',
                altText: 'random-image',
            }
        })
    </script>
</body>

4-8. methods attribute

ex)

08_methods.html

<body>
    <div id="app">
        {{ message }}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data: { 
                message:'Hello Vue!'
            },
            methods: {
                alertWarning: function() {
                    alert('WARNING!')
                },
                // Syntatic sugar : μœ„μ™€ μ•„λž˜λŠ” μ™„μ „νžˆ κ°™λ‹€!
                alertMessage(){
                    alert(this.message)
                    // Vue μ„Έμƒμ˜ this -> JS와 λ‹€λ₯΄κ²Œ 적용됨
                    // : λ‚΄λΆ€μ μœΌλ‘œ proxy system이 적용되기 λ•Œλ¬Έ 
                },
                changeMessage(){
                    this.message = 'Changed message'
                }
            }
        })
    </script>

4-9 v-on

  • listenerλ₯Ό λ“±λ‘ν•˜λŠ” 것

  • v-on: 을 μ€„μ—¬μ„œ @으둜 μ“Έ 수 μžˆλ‹€!

ex)

09_v-on.html

<body>
    <div id="app">
        <h1>{{ message }}</h1>
        <button v-on:click="alertWarning"> Alert Warning </button>
        <button v-on:click="alertMessage"> Alert Message </button>
        <button @click="changeMessage"> Change Message </button>
        <hr/>
        <!-- enter key λˆŒλ Έμ„ λ•Œ event λ°œμƒ-->
        <input v-on:keyup.enter="onKeyUp" type="text">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data: { 
                message:'Hello Vue!'
            },
            methods: {
                alertWarning: function() {
                    alert('WARNING!')
                },
                alertMessage(){
                    alert(this.message)
                },
                changeMessage(){
                    this.message = 'Changed message'
                },
                onKeyUp(event) {
                    this.message = event.target.value
                }
            }
        })
    </script>
</body>

4-10. v-model

input, select, textarea μ—μ„œλ§Œ κ°€λŠ₯ν•œ μ–‘λ°©ν–₯ binding

  • v-model λ””λ ‰ν‹°λΈŒλ₯Ό μ‚¬μš©ν•˜μ—¬ 폼 inputκ³Ό textarea μ—˜λ¦¬λ¨ΌνŠΈμ— μ–‘λ°©ν–₯ 데이터 바인딩을 생성할 수 μžˆλ‹€

  • v-model은 기본적으둜 μ‚¬μš©μž μž…λ ₯ μ΄λ²€νŠΈμ— λŒ€ν•œ 데이터λ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” β€œsyntax sugar” λ‹€

  • v-model은 λͺ¨λ“  form μ—˜λ¦¬λ¨ΌνŠΈμ˜ 초기 value와 checked 그리고 selected 속성을 λ¬΄μ‹œν•œλ‹€

    • 항상 Vue μΈμŠ€ν„΄μŠ€ 데이터λ₯Ό 원본 μ†ŒμŠ€λ‘œ μ·¨κΈ‰

    • μ»΄ν¬λ„ŒνŠΈμ˜ data μ˜΅μ…˜ μ•ˆμ— μžˆλŠ” JavaScriptμ—μ„œ μ΄ˆκΈ°κ°’μ„ 선언해야함!

ex)

10_v-model.html

<body>
    <div id="app">
        <h1> {{ message }}</h1>
        <!-- μ‚¬μš©μž μž…λ ₯ <=> dataλ₯Ό μ™„μ „νžˆ 동기화 μ‹œν‚€κ³  μ‹Άλ‹€! -->
        <!-- v-model => input, select, textarea μ—μ„œλ§Œ κ°€λŠ₯ν•œ μ–‘λ°©ν–₯ binding -->
        <hr/>
        <!-- 단방ν–₯ binding ( input => data )-->
        1way:
        <input @keyup="onInputChange" type="text">
        <hr/>
        <!-- μ–‘λ°©ν–₯ binding ( input <=> data )-->
        2way:
        <input @keyup="onInputChange" type="text" :value="message" />
        <hr/>
        <!-- v-model -->
        v-model/2way:
        <input v-model="message" type="text">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: 'hi',
            },
            methods: {
                onInputChange(event){    
                    this.message = event.target.value
                }
            }
        })
    </script>
</body>

4-11. v-show

  • v-if λŠ” 평가(t/f) κ°€ 자주 λ°”λ€Œμ§€ μ•Šμ„ λ•Œ μœ λ¦¬ν•˜λ‹€

  • => 초기 rendering costκ°€ 적닀

  • v-showλŠ” 평가 (t/f)κ°€ 자주 λ°”λ€” λ•Œ μ’‹λ‹€

    • => toggle costκ°€ 적닀

    • v-showλŠ” 이미 DOM 에 μ€€λΉ„ ν•΄λ†¨λŠ”λ° display만 none μž„!

ex)

11_v-show.html

<div id="app">
        <button @click="changeF">changeF</button>
        <p v-if="t">
            This is v-if with true
        </p>
        <p v-if="f">
            This is v-if with false
        </p>
        <p v-show="t">
            This is v-show with true
        </p>
        <p v-show="f">
            This is v-show wit false
        </p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        const app = new Vue({
            el:'#app',
            data: {
                t: true,
                f:false,
            },
            methods: {
                changeF(){
                    this.f = !this.f
                }
            }
        })
    </script>
</body>

+

Lodash

A modern JavaScript utility library delivering modularity, performance & extras.

https://lodash.com/

CDN

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

Last updated

Was this helpful?