템플릿 문법

KOO HEESEUNG·2022년 7월 10일
0

Vue.js 기초

목록 보기
6/6
post-thumbnail

템플릿 문법이란?

뷰 템플릿 문법은 뷰로 화면을 조작하는 방법.

데이터 바인딩

뷰 인스턴스에서 정의한 속성들을 화면에 표시하는 방법.
가장 기본적인 형태는 "Mustache” 구문(이중 중괄호)를 사용하는 것이다.

<h1>메시지 : {{ message }}<h1>

<script>
  new Vue({
    data: {
      message: "Hello Vue.js"
    }
  });
</script>

디렉티브

v- 접두사를 사용한 특수 속성으로, 디렉티브 속성값은 단일 JavaScript 표현식이 된다.
뷰로 화면 요소를 더 쉽게 조작할 수 있다.

v-if, v-else

v-if 를 사용하여 주어진 값의 참/거짓 여부에 따라 해당 요소를 화면에 출력할 수 있다.
v-else를 준 요소는 v-if의 값이 거짓일 때 대신 출력된다.

<p v-if="seen">seen의 값이 true면 볼 수 있는 메시지입니다.</p>
<p v-else>seen 값이 false면 볼 수 있는 메시지입니다.</p>

<script>
  new Vue({
    data: {
      seen: false
    },
  });
</script>

위 코드의 경우 두 번째 p 태그가 출력된다. seen 의 값이 false 이기 때문이다.

v-show 와의 차이

v-showv-if와 마찬가지로 참인 값이 주어졌을 때 화면에 출력되도록 하는 디렉티브이다.
그러나 v-show 에 주어진 값이 false 일 경우에는, 해당 엘리먼트가 존재하기는 하지만, style: "display" 속성이 none 이기 때문에 화면에 출력되지 않는 것이고, v-if 가 false 인 경우는 해당 엘리먼트가 아예 존재조차 하지 않는 경우이다.

v-for

예외적으로 v-for 은 단일 JavaScript 표현식이 아닌, 데이터 속성의 개수만큼 화면 요소를 반복 출력 가능하다.

<ul>
  <li v-for="car in cars">{{ car }}</li>
</ul>

<script>
  new Vue({
    data: {
      cars: ["bmw", "audi", "benz"]
    },
  });
</script>

v-bind

HTML 엘리먼트의 속성 값에는 머스태쉬 태그({{ }})를 쓰면 정상적으로 작동하지 않고, 경고가 발생한다.
이 경우 v-bind를 사용하여 HTML 엘리먼트 속성에 Vue 인스턴스 안의 데이터 값을 줄 수 있다.

<!-- v-bind:속성명="데이터명" -->
<a v-bind:href="url">...</a>

<script>
  new Vue({
    data: {
      url: "https://velog.io/@nrudev"
    },
  });
</script>

a 태그의 href 속성에 url 값을 연결하였다.

다음과 같이 v-bind를 생략하고 사용하는 것도 가능하다.
:(콜론) 만 남겨준다.

<a :href="url">...</a>

v-on

DOM 이벤트를 수신하는 디렉티브.
HTML 엘리먼트에 주어진 이벤트와 Vue 인스턴스 안의 메서드를 연결해줄 수 있다.

<!-- v-on:이벤트명="메소드명" -->
<button v-on:click="logText">...</button>

<script>
  new Vue({
    methods: {
      logText: function() {
        console.log('clicked');
      }
    }
  });
</script>

v-on 또한 v-bind 처럼 생략하여 작성할 수 있다.
v-on을 생략하는 대신 @를 붙여준다.

<button @click="logText">...</button>

computed 속성

템플릿 내에 표현식을 넣으면 편리하지만, 많은 연산을 템플릿 안에서 하면 코드가 비대해지고, 가독성이 떨어져 유지보수가 어렵다.
데이터의 연산은 computed 속성을 활용하는 편이 좋다.

<!-- 바람직하지 않은 방식 -->
<p>{{ message.split("").reverse().join("") }}</p>

<!-- 바람직한 방식 -->
<p>{{ reversedMessage }}</p>

<script>
  new Vue({
    data: {
      message: "안녕하세요"
    },
    computed: {
      reversedMessage: function() {
        return this.message.split("").reverse().join("");
      }
    }
  });
</script>

computed 속성의 장점

  1. 템플릿 코드의 가독성이 높아진다.
  2. computed 속성의 대상으로 정한 data 속성이 변했을 때, 자동으로 재연산하여 값을 갱신해준다.

computed 속성 사용시 주의사항

  1. computed 속성은 인자를 받지 않는다.
  2. HTTP 통신과 같은 컴퓨팅 리소스가 많이 필요한 로직을 정의하지 않는다.

watch 속성

특정 데이터의 변화에 따라 자동으로 특정 로직을 수행해주는 속성.

<div id="app">
  {{ num }}
  <button v-on:click="addNum">increase</button>
</div>

<script>
  new Vue({
    el: "#app",
    data: {
      num: 10,
    },
    watch: {
      num: function () {
        this.logText();
      },
    },
    methods: {
      addNum: function () {
        this.num = this.num + 1;
      },
      logText: function () {
        console.log("changed");
      },
    },
  });
</script>

위 코드는 버튼을 클릭하여 num 값이 변경되면 "changed"가 콘솔에 출력되도록 작성한 것이다.

watch 실용 문법

  1. watch 대상 속성에 함수를 연결하는 대신 메서드 함수를 연결할 수 있다.
new Vue({
  data() {
    return {
      message: 'Hello'
    }
  },
  methods: {
    logMessage() {
      console.log(this.message);
    }
  },
  watch: {
    'message': 'logMessage' // 대상 속성과 메서드 함수를 매칭
  }
});
  1. watch 대상 속성에 handler()immediate 속성을 정의할 수 있다.
new Vue({
  data() {
    return {
      message: 'Hello'
    }
  },
  watch: {
    'message': {
      handler(value, oldValue) {
        console.log(value);
      },
      immediate: true // 컴포넌트가 생성되자마자 즉시 실행
    }
  }
});

computed vs watch

computed 는 단순한 값에 대한 계산에,
watch 는 매번 실행되는 것이 부담스러운 무거운 로직(ex> HTTP 통신 등) 에 적합하다.

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

<script>
  new Vue({
    el: "#app",
    data: {
      num: 10,
    },
    computed: {
      doubleNum: function () {
        return this.num * 2;
      },
    },
    watch: {
      num: function (newValue, oldValue) {
        this.fetchUserByNumber(newValue);
      },
    },
    methods: {
      fetchUserByNumber: function (num) {
        axios.get(num);
      },
    },
  });
</script>

0개의 댓글