[Vue] Directives

문지은·2023년 6월 13일
0

Vue

목록 보기
2/15
post-thumbnail

Basic of Syntax

Template Syntax

  • Vue2 guide > Template Syntax 참고 템플릿 문법 — Vue.js
  • 렌더링 된 DOM을 기본 Vue instance의 data에 선언적으로 바인딩할 수 있는 HTML 기반 template syntax를 사용
    • 렌더링 된 DOM : 브라우저에 의해 보기 좋게 그려질 HTML 코드
    • HTML 기반 template syntax : HTML 코드에 직접 작성할 수 있는 문법 제공
    • 선언적으로 바인딩 : Vue instance와 DOM을 연결

Text Interpolation

  • 가장 기본적인 바인딩(연결) 방법
  • 중괄호 2개로 표기
  • DTL과 동일한 형태로 작성
  • Text interpolation 방법은 모두 일반 텍스트로 표현
<div id="app">
    <p>메시지: {{ msg }}</p>
    <p>HTML 메시지 : {{ rawHTML }}</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>

RAW HTML

  • v-html directive을 사용하여 data와 바인딩
  • directive - HTML 기반 template syntax
  • HTML의 기본 속성이 아닌 Vue가 제공하는 특수 속성의 값으로 data를 작성
<div id="app">
    <p>메시지: {{ msg }}</p>
    <span v-html="rawHTML"></span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            msg: 'RAW HTML',
            rawHTML: '<span style="color:red">빨간글씨</span>'
        }
    })
</script>

JS 표현식

  • 표현식 형태로 작성 가능
<div id="app">
    <p>메시지: {{ msg }}</p>
    <p>{{ msg.split('').reverse().join('') }}</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',
        }
    })
</script>

Directives

Directives 기본 구성

  • v-접두사가 있는 특수 속성에는 값을 할당 할 수 있음
    • 값에는 JS 표현식을 작성 할 수 있음
  • directive의 역할은 표현식의 값이 변경될 때 반응적으로 DOM에 적용하는 것

  • : 을 통해 전달인자를 받을 수 있음
  • . 으로 표시되는 특수 접미사 – directive를 특별한 방법으로 바인딩 해야 함

새 Vue instance 생성

  • 각각의 instance들은 연결된 DOM element에만 영향을 미침
  • 연결되지 않은 DOM이 Vue의 영향을 받지 않았던 것과 동일한 상황
<div id="app">
...
</div>

<div id="app2">
</div>

<!-- Vue CDN -->
<script>
	...
	const app2 = new Vue({
	el: '#app2',
	})
</script>

v-text

  • Template Interpolation과 함께 가장 기본적인 바인딩 방법
  • {{ }} 와 동일한 역할
    • 정확히 동일한 역할인 것은 아님
<div id="app">
  <p v-text="message"></p>
  <!-- 같음 -->
  <p>{{ message }}</p>
</div>

const app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!',
  }
})

v-html

  • RAW HTML을 표현할 수 있는 방법
  • 단, 사용자가 입력하거나 제공하는 컨텐츠에는 절대 사용 금지
    • XSS 공격 참고
<div id="app">
	<p v-html="html"></p>
</div>

<!-- Vue CDN -->
<script>
	const app = new Vue({
		el: '#app',
		data: {
			html: '<a href="https://www.google.com">GOOGLE</a>'
		}
	})
</script>

v-show

  • 표현식에 작성된 값에 따라 element를 보여줄 것인지 결정
    • boolean 값이 변경될 때마다 반응
  • 대상 element의 display 속성을 기본 속성과 none으로 toggle
  • 요소 자체는 항상 DOM에 렌더링 됨
<div id="app">
	<p v-show="isActive">보이니? 안보이니?</p>
</div>

<!-- Vue CDN -->
<script>
	const app = new Vue({
		el: '#app',
		data: {
			isActive: false
		}
	})
</script>
  • 바인딩 된 isActive의 값이 false이므로 첫 방문 시 p tag는 보이지 않음
    • vue dev tools에서 isActive 변경 시 화면에 출력
    • 값을 false로 변경 시 다시 사라짐

  • 화면에서만 사라졌을 뿐, DOM에는 존재한다.
    • display 속성이 변경되었을 뿐

v-if

  • v-show와 사용 방법은 동일
  • isActive의 값이 변경 될 때 반응
  • 단, 값이 false인 경우 DOM에서 사라짐
  • v-if v-else-if v-else 형태로 사용
<div id="app">
  <p v-if="isActive">안보이니? 보이니?</p>
</div>

<!-- Vue CDN -->
<script>
	const app = new Vue({
		el: '#app',
		data: {
			isActive: false
		}
	})
</script>

v-show VS v-if

  • v-show (Expensive initial load, cheap toggle)
    • 표현식 결과와 관계 없이 렌더링 되므로 초기 렌더링에 필요한 비용은 v-if 보다 높을 수 있음
    • display 속성 변경으로 표현 여부를 판단하므로 렌더링 후 toggle 비용은 적음
  • v-if (Cheap initial load, expensive toggle)
    • 표현식 결과가 false인 경우 렌더링조차 되지 않으므로 초기 렌더링 비용은 v-show 보다 낮을 수 있음
    • 단, 표현식 값이 자주 변경되는 경우 잦은 재 렌더링으로 비용이 증가할 수 있음

v-for

  • for .. in .. 형식으로 작성
  • 반복한 데이터 타입에 모두 사용 가능
  • index를 함께 출력하고자 한다면 (char, index) 형태로 사용 가능
<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>

<!-- Vue CDN -->
<script>
  const app = new Vue({
    el: '#app',
    data: {
      // 1. String
      myStr: 'Hello!',
		}
	})
</script>

  • 배열 역시 문자열과 동일하게 사용 가능
    • 각 요소가 객체라면 dot notation으로 접근 할 수 있음
<div id="app">
    <h2>Array</h2>
    <div v-for="(item, index) in myArr" :key="`ssafy-${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>

<!-- Vue CDN -->
<script>
  const app = new Vue({
    el: '#app',
    data: {
      // Array
      myArr: ['python', 'django', 'vue.js'],

      // Array with Object
      myArr2: [
        { id: 1, name: 'python', completed: true},
        { id: 2, name: 'django', completed: true},
        { id: 3, name: 'vue.js', completed: false},
		  ],
    }
  })
</script>

<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>

<!-- Vue CDN -->
<script>
  const app = new Vue({
    el: '#app',
    data: {
      // Object
      myObj: {
        name: 'harry',
        age: 27
      },
    }
  })
</script>

[참고] 특수 속성 key

  • “v-for 사용 시 반드시 key 속성을 각 요소에 작성”
  • 주로 v-for directive 작성 시 사용
  • vue 화면 구성 시 이전과 달라진 점을 확인 하는 용도로 활용
    • 따라서 key가 중복되어서는 안됨
  • 각 요소가 고유한 값을 가지고 있다면 생략할 수 있음
  • 객체 순회 시 value가 할당되어 출력
  • 2번째 변수 할당 시 key출력 가능
<div v-for="(item, index) in myArr2" :key="`arry-${index}`">
<p>{{ index.id }}번째 아이템</p>
<p>{{ item.name }}</p>
</div>

v-on

  • : 을 통해 전달받은 인자를 확인
  • 값으로 JS 표현식 작성
  • addEventListener의 첫 번째 인자와 동일한 값들로 구성
  • 대기하고 있던 이벤트가 발생하면 할당된 표현식 실행
<div id="app">
  <button v-on:click="number++">increase Number</button>
  <p>{{ number }}</p>
</div>

<!-- Vue CDN -->
<script>
    const app = new Vue({
      el: '#app',
      data: {
        number: 0,
      },
    })
  </script>

  • method를 통한 data 조작도 가능
  • method에 인자를 넘기는 방법은 일반 함수를 호출할 때와 동일한 방식
  • : 을 통해 전달된 인자에 따라 특별한 modifiers (수식어)가 있을 수 있음
    • ex) v-on:keyup.enter 등
    • vue2 가이드 > api > v-on 파트 참고
  • @ shortcut 제공
    • ex) @keyup.click
<div id="app">
	<button v-on:click="toggleActive">toggle isActive</button>
  <p>{{ isActive }}</p>

  <button @click="checkActive(isActive)">check isActive</button>
</div>

<!-- Vue CDN -->
<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-bind

  • HTML 기본 속성에 Vue data를 연결
  • class의 경우 다양한 형태로 연결 가능
    • 조건부 바인딩 : { ‘class Name’: ‘조건 표현식’ }
      • 삼항 연산자도 가능
    • 다중 바인딩 : [‘JS 표현식’, ‘JS 표현식’, ...]
  • Vue data의 변화에 반응하여 DOM에 반영하므로 상황에 따라 유동적 할당 가능
  • : shortcut 제공
    • ex) :class 등
    • v-for 에서 사용하였던 :key는 v-bind의 shortcut을 활용한 것
<style>
	.red-text {
	    color: red;
	}
	
	.border-black {
	    border: solid 1px black;
	}
</style>

<div id="app">
    <a v-bind:href="url">Go To GOOGLE</a>
    <!-- v-bind는 생략가능 -->
    <p :class="redTextClass">빨간글씨</p>
    <!-- 조건부 바인딩 -->
    <p :class="{ 'red-text': true }">빨간글씨</p>
    <!-- 다중 바인딩 -->
    <p :class="[redTextClass, borderBlack]">빨간글씨, 테두리</p>
</div>

<!-- Vue CDN -->
<script>
    const app = new Vue({
        el :'#app',
        data: {
            url: 'https://www.google.com',
						redTextClass: 'red-text',
            borderBlack: 'border-black',
        },
    })
</script>

  • 다크 모드 토글 버튼 만들기
<style>
	.dark-mode {
	    color: white;
	    background-color: black;
	}
	
	.white-mode {
	    color: black;
	    background-color: white;
	}
</style>

<div id="app">
	<p :class="theme">모드 전환</p>
	<button @click="darkModeToggle">{{ theme }} 모드 토글</button>
</div>

<!-- Vue CDN -->
<script>
  const app = new Vue({
      el :'#app',
      data: {
          isAcitve: true,
          theme: 'dark-mode',
      },
      methods: {
          darkModeToggle() {
              this.isAcitve = !this.isAcitve
              if (this.isAcitve) {
                  this.theme = 'dark-mode'
              } else {
                  this.theme = 'white-mode'
              }
          }
      }
  })
</script>

v-model

  • Vue instance와 DOM의 양방향 바인딩
  • Vue data 변경 시 v-model로 연결된 사용자 입력 element에도 적용
<div id="app">
	<h3>{{ myMessage }}</h3>
	<input v-model="myMessage" type="text">
	<hr>
</div>

<!-- Vue CDN -->
<script>
	const app = new Vue({
		el: '#app',
		data: {
			myMessage: '',
		},
	})
</script>

📍 전체 코드 확인

https://github.com/mjieun0956/TIL/tree/master/Vue/02.%20Directives

profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글