Template Syntax

렌더링 된 DOM을 기본 Vue instance의 data에 선언적으로 바인딩 할 수 있는 HTML 기반 template syntax를 사용한다.

렌더링 된 DOM  - 브라우저에 의해 보기 좋게 그려질 HTML 코드

HTML 기반 template syntax - HTML 코드에 직접 작성할 수 있는 문법 제공

선언적으로 바인딩 - Vue instance와 DOM을 연결

 

 

https://v2.vuejs.org/v2/guide/syntax.html

 

Template Syntax — Vue.js

Vue.js - The Progressive JavaScript Framework

v2.vuejs.org

 

 

Text interpolation

  <div id="app">
    <p>메시지: {{ msg }}</p>   
    <p>HTML 메시지 : <span v-html="rawHTML"></span></p>
  </div>
  
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        msg: 'Text interpolation',
        rawHTML: '<span style="color:red"> 빨간 글씨</span>'
      }
    })
  </script>

가장 기본적인 바인딩(연결) 방법으로 중괄호 2개로 표기한다.

DTL과 동일한 형태로 작성한다.

template interpolation 방법은 HTML 을 일반 텍스트로 표현한다.

일반텍스트로 표현한 HTML은 태그의 v-html으로 연결한다. v-html directive를 사용하여 data와 바인딩 한다.

HTML의 기본 속성이 아닌 Vue가 제공하는 특수 속성의 값으로 data를 작성한다.

 

 

vue의 {{msg}}이 반영되었고, rawHTML이 HTML로 잘 연결된 것을 확인할 수 있다.

 

 

  <div id="app">
    <p>메시지: {{ msg }}</p>   
    <p>HTML 메시지 : <span v-html="rawHTML"></span></p>
    <p>{{ msg.split('').reverse().join('') }}</p>
  </div>

msg를 JS 표현식 형태로도 작성 가능하다.

 

 

directives

v-접두사가 있는 특수 속성에는 값을 할당할 수 있다.

값에는 JS 표현식을 작성할 수 있다.

directive의 역할은 표현식의 값이 변경될 때 반응적으로 DOM에 적용하는 것

 

v-text

v-html

  <div id="app2">
    <p v-text="message"></p>
    <p>{{ message }}</p>
    <p v-html="html"></p>
  </div>
  
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
      const app2 = new Vue({
      el: '#app2',
      data: {
        message: 'Hello!',
        html: '<a href="https://www.google.com">GOOGLE</a>'
      }
    })
    </script>

v-text

template interpolation과 함께 가장 기본적인 바인딩 방법

{{ }}과 같은 역할을 한다.

 

 

v-html

raw html을 표현할 수 있는 방법

단, 사용자가 입력하거나 제공하는 컨텐츠에는 절대 사용 금지 !

 

 

v-show

  <div id="app3">
    <p v-show="isActive">보이니? 안보이니?</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app3 = new Vue({
      el: '#app3',
      data: {
        isActive: false
      }
    })
  </script>

표현식에 작성된 갑셍 따라 element를 보여줄 것인지 결정 (boolean 값이 변경 될 때 마다 반응)

대상 element의 display 속성을 기본 속성과 none으로 toggle 된다.

요소 자체는 항상 DOM에 렌더링 되어있고, 보이는지 아닌지가 달라지는 것이다.

 

isActive 요소가 false로 되어있고,

개발자도구의 태그에서 display:none을 확인할 수 있다.

요소가 보이지 않을 뿐 항상 DOM에 렌더링 된다.

 

 

 

isActive:true로 변경하면 요소가 보인다.

 

 

 

v-if

  <div id="app3">
    <p v-show="isActive">보이니? 안보이니?</p>
    <p v-if="isActive">v-if 안보이니? 보이니?</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app3 = new Vue({
      el: '#app3',
      data: {
        isActive: false
      }
    })
  </script>

v-show와 사용방법은 동일하지만, false인 경우 값이 DOM에서 사라진다.

false일 때 화면에서 p 태그 둘다 보이지 않지만, 개발자도구의 태그를 확인하면 v-show 태그는 display:none으로 되어있을 뿐 태그는 존재한다. v-if 태그는 존재하지 않는다.

v-if, v-else-if, v-else 형태로 사용할 수 있다.

 

 

 

v-show, v-if 비교

v-show

표현식 결과와 관계없이 렌더링 되므로 초기 렌더링에 필요한 비용은 v-if보다 높을 수 있다.

display 속성 변경으로 표현 여부를 판단하므로 렌더링 후 toggle비용은 적다.

 

v-if

표현식 결과가 false인 경우는 렌더링조차 되지 않기 때문에 초기 렌더링 비용은 v-show 보다 낮을 수 있다.

표현식 값이 자주 변경되는 경우 잦은 재 렌더링으로 비용이 증가할수 있다.

 

 

v-for

for .. in .. 형식으로 작성한다.

index를 함께 출력하기 위해서는 (char, index) 형태로 사용 가능하다.

각 요소가 객체라면 dot notation으로 접근할 수 있다.

 

 

v-for 문자열

  <div id="app">
    <h2>String</h2>
    <div v-for="char in myStr">
      {{char}}
    </div>
 </div>
   
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        myStr: 'Hello, World!',
      }
    })
  </script>

  <div id="app">
    <h2>String</h2>
    <div v-for="char in myStr">
      {{char}}
    </div>
    <div v-for="(char, index) in myStr" :key="index">
      <p>{{ index }}번째 문자열 {{ char }}</p>
    </div>
  </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        myStr: 'Hello, World!',
      }
    })
  </script>

 

 

v-for 배열

  <div id="app">
       <h2>Array</h2>
    <div v-for="(item, index) in myArr" :key="index">
      <p>{{ index }}번째 아이템 {{ item }}</p>
    </div> 
  </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        myStr: 'Hello, World!',
        myArr: ['python', 'django', 'vue.js'],
      }
    })
  </script>

 

 

 

  <div id="app">
       <h2>Array</h2>
    <div v-for="(item, index) in myArr" :key="index">
      <p>{{ index }}번째 아이템 {{ item }}</p>
    </div> 
     <div v-for="(item, index) in myArr2" :key="`arry-${index}`">
      <p>{{ index }}번째 아이템</p>
	<p>{{ item.name }}</p>
    </div>
  </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        myStr: 'Hello, World!',
        myArr: ['python', 'django', 'vue.js'],
        myArr2: [
          { id: 1, name: 'python', completed: true},
          { id: 2, name: 'django', completed: true},
          { id: 3, name: 'vue.js', completed: false},
			  ],
      }
    })
  </script>

v-for 사용시 반드시 key 속성을 각 요소에 작성해야 한다.

vue 화면 구성시 이전과 달라진 점을 확인하는 용도로 활용해야 하기 때문에 key가 중복되어서는 안된다.

각 요소가 고유한 값을 가지고 있지 않다면 생략할 수 있다.

 

 

 

 

  <div id="app">
    <h2>Object</h2>
    <div v-for="value in myObj">
      <p>{{ value }}</p>
    </div>

    <div v-for="(value, key) in myObj"  :key="key">
      <p>{{ key }} : {{ value }}</p>
    </div>
  </div>
 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        myStr: 'Hello, World!',
        myArr: ['python', 'django', 'vue.js'],
        myArr2: [
          { id: 1, name: 'python', completed: true},
          { id: 2, name: 'django', completed: true},
          { id: 3, name: 'vue.js', completed: false},
			  ],
        myObj: {
          name: 'harry',
          age: 27
        },
      }
    })
  </script>

 

 

 

 

v-on

: 을 통해 전달받은 인자를 확인한다.

값으로 JS 표현식 작성 가능하다.

addEventListener의 첫번째 인자와 동일한 값들로 구성된다.

대기하고 있던 이벤트가 발생하면 할당된 표현식 실행한다.

<body>
  <div id="app">
    <button v-on:click="number++">increase Number</button>
    <p>{{ number }}</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        number: 0,
      },
    })
  </script>

v-on:click="number++"

버튼을 클릭하면 number++ 동작을 하게 된다. 

number은 data에 0으로 지정되어 있다. 버튼을 누르면 0, 1, 2, 3... 실시간으로 증가하여 반영된다.

 

 

 

<body>
  <div id="app">
    <button v-on:click="number++">increase Number</button>
    <p>{{ number }}</p>
    <button v-on:click="toggleActive">toggle isActive</button>
    <p>{{ isActive }}</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        number: 0,
        isActive: false,
      },
      methods: {
        toggleActive: function () {
          this.isActive = !this.isActive
        },
      }
    })
  </script>

메서드를 실행하는 동작을 할 수도 있다.

isActive바꿔주는 toggleActive라는 메서드를 지정해주었고, v-on:click="toggleActive"로 클릭시 메서드를 실행하도록 했다.

isActive인자를 사용했다.

해당 버튼을 누르면 true, false가 번갈아가면서 출력된다.

 

 

 

<body>
  <div id="app">
    <button v-on:click="number++">increase Number</button>
    <p>{{ number }}</p>
    <button v-on:click="toggleActive">toggle isActive</button>
    <p>{{ isActive }}</p>
    <button @click="checkActive(isActive)">check isActive</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        number: 0,
        isActive: false,
      },
      methods: {
        toggleActive: function () {
          this.isActive = !this.isActive
        },

        checkActive: function (check) {
          console.log(check)
        }
      }
    })
  </script>

v-on:click = "checkActive(isActive)" 

@click = "checkActive(isActive)" 

@ shortcut이 제공된다.

isActive를 인자로 가져가는 checkActive 메서드를 실행한다.

 

 

v-bind

HTML 기본 속성에 Vue data를 연결한다.

class의 경우 다양한 형태로 연결 가능하다.

 

 

 <div id="app2">
    <a v-bind:href="url">Go To GOOGLE</a>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app2 = new Vue({
      el: '#app2',
      data: {
        url: 'https://www.google.com/',
      },
    })
  </script>

v-bind:href="url"

Go To GOOGLE 글자에 data의 url의 값이 바인딩된다.

vue data의 변화에 반응하여 DOM에 반영하므로 상황에 따라 유동적으로 할당 가능하다.

: shortcut 제공 (v-for 에서 사용했던 :key는 v-bind의 shortcut을 활용한 것이다.)

 

 

 <div id="app2">
    <a v-bind:href="url">Go To GOOGLE</a>
    <p v-bind:class="redTextClass">빨간 글씨</p>
    <p v-bind:class="{ 'red-text': true }">빨간 글씨</p>
    <p v-bind:class="[redTextClass, borderBlack]">빨간 글씨, 검은 테두리</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
       const app2 = new Vue({
      el: '#app2',
      data: {
        url: 'https://www.google.com/',
        redTextClass: 'red-text',
        borderBlack: 'border-black',
      }
    })
  </script>

v-bind로 클래스를 연결했다.

 

조건부 바인딩

{'class Name' : '조건 표현식'}

다중 바인딩

['JS 표현식', 'JS표현식' ...]

 

 

 

 <div id="app2">
     <p :class="theme">상황에 따른 활성화</p>
    <button @click="darkModeToggle">dark Mode {{ isActive }}</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
       const app2 = new Vue({
      el: '#app2',
      data: {
        isActive: true,
        theme: 'dark-mode'
      },
      methods: {
        darkModeToggle() {
          this.isActive = !this.isActive
          if (this.isActive) {
            this.theme = 'dark-mode'
          } else {
            this.theme = 'white-mode'
          }
        }
      }
    })
  </script>

isActive 상태를 바꿔주고 그 상태에 따라 dark-mode, white-mode의 theme을 변경해주는 메서드를 만들었다.

클릭하면 메서드를 실행하는 버튼이 있고, p태그에는 :class="theme"으로 theme이 바인딩되어 있다.

버튼을 클릭하면 버튼 내용이 바뀌고, theme이 변경되어 적용된다.

 

 

 

 

 

v-model

v-on

  <div id="app">
    <h3>{{ myMessage }}</h3>
    <input @input="onInputChange" type="text">
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        myMessage: '',
      },
      methods: {
        onInputChange: function (event) {
          this.myMessage = event.target.value
        },
      }
    })
  </script>

v-on:input (@input) 입력 이벤트가 발생할 때 onInputChange라는 메서드를 실행한다.

이 메서드는 event.target ( input 태그) 의 value(입력 값)을 myMessage로 반영하는 것이다.

입력 (이벤트) -> 함수 실행 -> model 반영으로 바인딩되었다.

이것을 입력과 동시에 반영되는 양방향 바인딩하기 위해 v-model을 쓸 수 있다.

 

v-model

Vue instance와 DOM의 양방향 바인딩

Vue data 변경 시 v-model로 연결된 사용자 입력 element에도 적용된다.

  <div id="app">
    <h3>{{ myMessage }}</h3>
    <input v-model="myMessage" type="text">
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        myMessage: '',
      }
    })
  </script>

v-model="myMessage"를 연결했기 때문에 input을 입력하면 {{myMessage}}도 적용된다.