본문 바로가기
Vue.js

#4. Vue.js - 템플릿 문법, 양방향 데이터바인딩, 데이터변화 감지

by Ristonia 2023. 8. 8.

1.템플릿 문법이란

뷰의 템플릿은 HTML, CSS 등의 마크업속성과 뷰 인스턴스에서 정의한 데이터 및 로직들을 연결해 브라우저에서 볼 수 있는 형태의 HTML로 변환해주는 속성을 말한다.

여기서 템플릿 문법이란 뷰로 화면을 조작하는 '방법'을 의미하며 템플릿 문법은 크게 데이터바인딩과 디렉티브로 나뉜다.

1-1. 데이터바인딩

데이터바인딩은 뷰 인스턴스에서 정의한 속성들을 화면에 표시하는 방법으로 가장 기본적인 데이터 바인딩 방식은 콧수염괄호({{}}) 이며, 이외에 v-bind 속성이 있다.

new Vue({
   template : '<p>{{message}}</p>'
});
<p v-bind:id="bindId">id바인딩</p>
new Vue({
  data : {
      bindId : 'myId'
   }
})

 

라이브러리 내부적으로 template 속성에서 정의한 마크업 + 뷰 데이터를 가상 돔 기반의 render() 함수로 변환한다.

변환된 render() 함수는 최종적으로 사용자가 볼 수 있게 화면을 그리는 역할을 한다.

문법 설명
{{}} 뷰 인스턴스의 데이터를 HTML 태그에 연결하는 텍스트 삽입 방식이다.
v-bind 아이디,클래스,스타일 등의 HTML 속성 값에 뷰 데이터값을 연결할 때 사용한다.

 

1-2. 디렉티브

디렉티브는 뷰로 화면의 요소를 더 쉽게 조작하기 위한 문법으로 화면 조작에서 자주 사용되는 방식들을 모아 디렉티브형태로 제공한다.

HTML 태그안에 v- 접두사를 가지는 모든 속성들을 의미한다.

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

디렉티브이름 설명
v-if 지정한 뷰 데이터의 참,거짓에 따라 HTML 표시 여부를 선택한다.
v-for 지정한 뷰 데이터의 개수만큼 HTML 태그를 반복출력한다.
v-show v-if와 유사하게 데이터의 참,거짓에 따라 HTML 표시 여부를 선택한다.
, v-if는 해당 태그를 완전삭제하지만 v-show css display:none; 처리를 하는것이 다르다.
v-bind HTML 태그의 기본 속성과 뷰 데이터 속성을 연결한다.
v-bind 디렉티브를 줄여쓰는 방법 ex) v-bind:src  :src 로 작성 가능
v-on 화면 요소의 이벤트를 감지하여 처리할 때 사용한다.
예를들어 v-on:click 은 해당 태그의 클릭 이벤트를 감지하여 특정 메소드를 실행시킨다.
v-on 디렉티브를 줄여쓰는 방법 ex) v-on:click  @click 로 작성가능 
v-model form 태그에서 주로 사용되는 속성이다.
form에 입력한 값을 뷰 인스턴스의 데이터와 즉시 동기화한다.
화면에 입력된 값을 저장하여 서버에 보내거나 watch와 같은 고급 속성을 이용하여 추가 로직을 수행할 수 있다.
<input>,<select>,<textarea> 태그에만 사용할 수 있다.
v-text,{{}} 태그 문자열을 HTML 인코딩하여 나타내기 때문에 화면에 태그 문자열이 그대로 나타난다.
v-html <sciprt> 태그를 그대로 바인딩하여 XSS에 취약. v-text를 사용하는것이 안전하다.

 

이 외, 다른 디렉티브에 대한 상세설명은 공식문서를 보고 참고하도록 하자.

공식문서 https://vuejs.org/v2/guide/forms.html#Text

 

 

{{}}표현식이 화면에 잠깐 나타났다가 사라질때가 있는데 보이지않게 처리하기 위한 디렉티브로 v-cloak이 있다.

 

[v-cloak] :{display:none;}

 

 

 

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <p v-bind:id="uuid" v-bind:class="name">{{ num }}</p>
    <!-- <p id="abc1234">{{ num }}</p> -->
    <p>{{ doubleNum }}</p>
    <div v-if="loading">
      Loading...
    </div>
    <div v-else>
      test user has been logged in
    </div>
    <div v-show="loading">
      Loading...
    </div>
    <input type="text" v-model="message">
    <p>{{ message }}</p>
  </div>
 
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    new Vue({
      el: '#app',
      data: {
        num: 10,
        uuid: 'abc1234',
        name: 'text-blue',
        loading: true,
        message: ''
      },
      computed: {
        doubleNum: function() {
          return this.num * 2;
        }
      }
    })
  </script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <button v-on:click="logText">click me</button>
    <input type="text" v-on:keyup.enter="logText"><!--이벤트모디파이어 .으로 접근 enter시에만 해당메소드를 실행-->
    <button>add</button>
  </div>
 
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    new Vue({
      el: '#app',
      methods: {
        logText: function() {
          console.log('clicked');
        }
      }
    })
  </script>
</body>
</html>

1-3. watch 속성 vs computed 속성

Vue에서 속성이 변경될 때 변화에 대응하고 싶을 때 watch 속성 및 computed을 사용할 수 있다.

 

참조하고 있는 값이 변경될 때마다 정의된 계산식에 따라 값을 출력하는 computed와 다르게, watch는 값이 변경될 때 실행되는 함수를 지정할 수 있다.

 computed가 계산된 값을 출력하는 용도라면 watch는 어떤 조건이 되었을 때 함수를 실행시키기 위한 트리거로서 사용할 수 있다는 의미이다.

 

데이터 변화를 감지하여 특정 로직이 샐행되는 watch의 속성에 따라, watch는 매번 실행되기 부담스러운 로직이나 상대적으로 처리시간이 긴 데이터요청작업 등을 처리하는데 있어서 적합하며

텍스트연산이나 validation 체크 같은 기능은 computed가 적합하다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app">
    {{ num }}
  </div>
 
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    new Vue({
      el: '#app',
      data: {
        num: 10
      },
      computed: {
        doubleNum: function() {
          return this.num * 2;
        }
      },
      watch: {
        num: function(newValue, oldValue) {
          this.fetchUserByNumber(newValue,oldValue);
        }
      },
      methods: {
        fetchUserByNumber: function(newValue,oldValue) {
           console.log(newValue,oldValue);
          axios.get(newValue);
        }
      }
    });
  </script>
</body>
</html>
 
      }
    })
  </script>
</body>
</html>

 

다음과 같이 computed 속성을 사용하여 클래스 코드를 작성할 수도 있다.

템플릿표현식에 작성하는것이 아닌 스크립트단으로 소스를 내려 직관적으로 표현할 수도 있다.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
  .warning {
    color: red;
  }
  </style>
</head>
<body>
  <div id="app">
    <p v-bind:class="cname">Hello</p>
    <p v-bind:class="{ warning: isError}">Hello</p> <!--warning이라는 클래스를  조건에 따라 출력여부를 판단-->
                                                    <!--isError 값이 true 빨간색 스타일 적용-->
    <p v-bind:class="errorTextColor">Hello</p> <!-- { warning: isError} 계산식을 errorTextColor 텍스트로 대체 (computed 속성 사용) -->
  </div>
   
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    new Vue({
      el: '#app',
      data: {
        // cname: 'blue-text',
        isError: true
      },
      computed: {
        errorTextColor: function() {
          return this.isError ? 'warning' : null;
        }
      }
    });
  </script>
</body>
</html>

'Vue.js' 카테고리의 다른 글

#6. Vue.js - Vuex  (0) 2023.08.08
#5. Vue.js - Vue CLI  (0) 2023.08.08
#3. Vue.js - Routing(페이지이동), Axios(API 비동기 통신)  (0) 2023.08.08
#2. Vue.js - 컴포넌트 통신규칙  (1) 2023.08.08
#1. Vue.js 란?  (1) 2023.08.08