본문 바로가기

FrontEnd

뷰 템플릿

728x90

템플릿(template) : HTML, CSS 등의 마크업 속성과 뷰 인스턴스에서 정의한 데이터 및 로직들을 연결하여 사용자가 브라우저에서 볼 수 있는 형태의 HTML로 변환해주는 속성

 

1. ES5에서 뷰 인스턴스의 template 속성 활용

ex. template: <p>Hello {{message}}</p>와 같은 코드

 

template 속성에서 정의한 마크업 + 뷰 데이터를 가상 돔 기반의 render()함수로 변환한다

변환된 render() 함수는 최종적으로 사용자가 볼 수 있게 화면을 그리는 역할이고 변환 과정에서 뷰의 반응성이 화면에 더해진다고 한다

 

2. 싱글 파일 컴포넌트 체계의 <template> 코드를 활용하는 방법

<template>
	<p>Hello {{message}}</p>
</template>

 

 

데이터 바인딩

데이터 바인딩(Data Binding) : HTML 화면 요소를 뷰 인스턴스의 데이터와 연결하는 것

주요 문법으로는 {{ }}문법과 v-bind 속성이 있음

 

{{ }} - 콧수염 괄호(?)

: 뷰 인스턴스의 데이터를 HTML 태그에 연결하는 가장 기본적인 텍스트 삽입 방식

<div id="app">
  {{ message }}
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue.js!'
    }
  });
</script>

data 속성의 message 속성 값인 Hello Vue.js!를 <div> 태그 안의 {{message}}에 연결하여 화면에 나타내는 코드

data 속성의 message 값이 바뀌면 뷰 반응성에 의해 화면이 자동으로 갱신됨

 

<div id="app" v-once>
  {{ message }}
</div>

뷰 데이터가 변경되어도 값을 바꾸고 싶지 않을 때는 v-once 속성을 사용하기

 

v-bind : 아이디, 클래스, 스타일 등의 HTML 속성(attributes) 값에 뷰 데이터 값을 연결할 때 사용하는 데이터 연결 방식

<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="app">
      <p v-bind:id="idA">아이디 바인딩</p>
      <p v-bind:class="classA">클래스 바인딩</p>
      <p v-bind:style="styleA">스타일 바인딩</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        data: {
          idA: 10,
          classA: 'container',
          styleA: 'color: blue'
        }
      });
    </script>
  </body>
</html>

 

위 그림을 보자!

idA, classA, styleA 값이 화면의 요소에 각각 연결되어 10, container, color: blue로 나타난 게 보인다 개신기해!

 

 

자바스크립트 표현식

뷰의 템플릿에서 {{ }}에 자바스크립트 표현식을 넣어서 사용할 수 있다

<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="app">
      <p>{{ message }}</p>
      <p>{{ message + "!!!" }}</p>
      <p>{{ message.split('').reverse().join('') }}</p>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        data: {
          message: 'Hello Vue.js!'
        }
      });
    </script>
  </body>
</html>

 

자바스크립트 표현식을 사용해서 !!!도 추가해보고 반대로 출력도 해봤다

자바스크립트 문법 좀 까먹었는데 대충 공백기준으로 나눠서 반대로 출력하는 것인듯

 

<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="app">
      {{ var a=10; }} <!--선언문은 사용X-->
      {{ if(true) {return 100} }} <!--분기구문 사용X-->
      {{ true ? 100 : 0 }} <!--삼항 연산자O-->

      {{ message.split('').reverse().join('') }} <!--복잡한 연산은 인스턴스 안에서 수행되어서 X-->
      {{ reversedMessage }} <!--스크립트에서 computed속성으로 계산한 후 최종 값만 표현됨-->
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        data: {
          message: 'Hello Vue.js!'
        },
        computed: { //데이터 속성을 자동으로 계산해주는 속성
          reversedMessage: function() { //{reversedMessage}}에 표현되기 전에 연산을 수행하는 함수
            return this.message.split('').reverse().join('');
          }
        }
      });
    </script>
  </body>
</html>

message의 텍스트 값을 역순으로 변환하는 연산은 HTML단에서 수행되지 않음 <- HTML에 최종적으로 표현될 값만 나타내고 데이터의 기본 연산은 자바스크립트 단에서 함으로써 화면단 코드의 가독성을 높일 수 있기 때문

 

자바스크립트 단에서 computed 속성을 이용하여 계산한 후 최종 결과 값만 표시함

 

 

디렉티브

뷰 티렉티브(Directive) : HTML 태그 안에 v-접두사를 가지는 모든 속성들을 의미

- 화면의 요소를 더 쉽게 조작하기 위해 사용하는 기능

- 뷰의 데이터 값이 변경되었을 때 화면의 요소들이 리액티브(Reactive)하게 반응하여 변경된 데이터 값에 따라 갱신됨

 

v-if 지정한 뷰 데이터 값의 참, 거짓 여부에 따라 해당 HTML 태그를 화면에 표시하거나 표시하지 않음
v-for 지정한 뷰 데이터의 개수만큼 해당 HTML 태그를 반복 출력
v-show v-if와 비슷하게 데이터의 진위여부에 따라 해당 HTML 태그를 화면에 표시하거나 표시하지 않는다
v-if는 해당 태그를 완전히 삭제하지만, v-show는 css효과만 display:none;으로 주어 실제 태그는 남아있고 화면에는 보이지 않는다
v-bind HTML 태그의 기본 속성과 뷰 데이터 속성을 연결
v-on 화면 요소의 이벤트를 감지하여 처리할 때 사용.
v-model 폼(form)에서 주로 사용됨. 폼에 입력한 값을 뷰 인스턴스의 데이터와 즉시 동기화함
화면에 입력된 값을 저장하여 서버에 보내거나 watch와 같은 고급 속성을 이용하여 추가로직을 수행할 수 있음
<input>, <select>, <textarea> 태그에만 이용 가능

 

<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="app">
      <a v-if="flag">Vue.js</a>
      <ul>
        <li v-for="system in systems">{{system}}</li>
      </ul>
      <p v-show="flag">Node.js</p>
      <h5 v-bind:id="uid">뷰 입문서</h5>
      <button v-on:click="popupAlert">경고 창 버튼</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        data: {
          flag: true, //v-if 조건 값이 true이므로 Vue.js가 화면에 출력 //v-show값이 true이므로 Node.js가 출력
          systems: ['android', 'ios', 'windows'], //배열의 요소 개수만큼 반복(for) 되 출력 
          uid: 10 //id속성을 uid값과 연결하여 10을 출력
        },
        methods: {
          popupAlert: function () {
            return alert('경고 창 표시'); //경고창버튼 클릭시 해당 이벤트를 감지하여 수행된다
          }
        }
      });
    </script>
  </body>
</html>

 

- v-if와 v-for에서 flag가 true가 되어서 Vue.js와 Node.js가 출력되었다

- 리스트로 배열 systems의 요소가 하나씩 꺼내져서 출력됨

- 출력 화면에서 큰 변화는 보이지않지만 v-bind의 값이 10으로 되었다

- button으로 경고 창 버튼이 있도록 하였는데 click같은 이벤트가 발생하면 popupAlert함수가 실행되어서 경고 창 표시라는 메세지가 뜨도록 함

 

만약 false였다면 Vue.js, Node.js가 출력되지 않았겠지?

더불어, 이벤트가 발생하지 않으니 경고 창 표시라는 메세지도 뜨지 않을테고

 

 

이벤트 처리

뷰에서 화면에서 발생한 이벤트를 처리하기 위해 v-on 디렉티브와 methods 속성을 활용한다

<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="app">
      <button v-on:click="cliBut">클릭</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        methods: {
          cliBut: function () {
            alert('클릭됨'); //경고창버튼 클릭시 해당 이벤트를 감지하여 수행된다
          }
        }
      });
    </script>
  </body>
</html>

 

v-on 디렉티브로 메서드를 호출할 때 인자를 넘길 수도 있다!

<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="app">
      <button v-on:click="cliBut(10)">클릭</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        methods: {
          cliBut: function (num) {
            alert('클릭됨' + num + '더하기' + (num+10));
          }
        }
      });
    </script>
  </body>
</html>

 

event 인자를 이용해 화면 요소의 돔 이벤트에 접근해보자

<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="app">
      <button v-on:click="cliBut">클릭</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        methods: {
          cliBut: function (event) {
            console.log(event);
        }
      }
      });
    </script>
  </body>
</html>

 

고급 템플릿 기법

computed 속성

데이터를 가공하는 등 복잡한 연산은 뷰 인스턴스 안에서!

HTML에는 데이터를 표현만! 해야한다. 그래서 computed 속성은 이러한 데이터 연산들을 정의하는 영역이다

○ data 속성 값의 변화에 따라 자동으로 다시 연산한다

○ 캐싱 : 동일한 연산을 반복해서 하지 않기 위해 연산의 결과 값을 미리 저장하고 있다가 필요할 때 불러오는 동작

 

computed 속성 vs methods 속성

- methods 속성은 호출할 때만 해당 로직이 수행된다(수동적)

- computed 속성은 대상 데이터의 값이 변경되면 자동적으로 수행된다(능동적)

 

<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="app">
      <p>{{ message }}</p>
      <button v-on:click="revMsg">문자열 역순</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        data: {
          message: 'Hello Hello omg'
        },
        methods: {
          revMsg: function(){
            this.message = this.message.split('').reverse().join('');
            return this.message;
          }
        }
      });
    </script>
  </body>
</html>

 

computed 속성과 문자열을 뒤집은 결과를 내지만, 위 코드에서는 [문자열 역순]이라는 버튼을 눌러야만 바뀐다는 점!

 

캐싱 면에서 methods 속성은 수행할 때마다 연산을 하기 때문에 별도로 캐싱을 하지 않음

computed 속성은 데이터가 변경되지 않는 한 이전의 계산 값을 가지고 있다가 필요할 때 바로 반환해줌

 

성능면에서는 computed가 win!

 

 

watch 속성

데이터 변화를 감지하여 자동으로 특정 로직을 수행

데이터 호출과 같이 시간이 더 많이 소모되는 비동기 처리에 적합하다

<!DOCTYPE html>
<html lang="ko" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div id="app">
      <input v-model="message">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        data: {
          message: 'Hello Hello omg'
        },
        watch: {
          message: function(data){
            console.log("message의 값이 바뀐다 : ", data);
          }
        }
      });
    </script>
  </body>
</html>

input 박스 안의 문자열이 달라지면 콘솔에 변화는 값이 출력된다

 

728x90

'FrontEnd' 카테고리의 다른 글

Vue.js 뷰 HTTP 통신  (0) 2022.07.28
Vue.js 뷰 라우터 | 네스티드 뷰 | 네임드 뷰  (0) 2022.07.28
Vuejs 뷰 컴포넌트 통신  (0) 2022.07.27
Vue.js 컴포넌트  (0) 2022.07.25
Vue.js 기초 | 라이프사이클  (0) 2022.07.25