티스토리 뷰

Vue

Vue.js 기본 디렉티브

인삼추출물 2021. 1. 4. 08:37

(공부 책 : Vue.js Quick Start )

1. ex01-01.html 분석

<body>
    <div id="ex01_01">
        <h2>{{message}}</h2>
    </div>
    <script type="text/javascript">
        var model = {
            message: 'Hello World!'
        };

        var ex01_01 = new Vue({
            el: '#ex01_01',
            data: model
        })
    </script>
</body>

코드 내 

var model = {  
    message: 'Hello World!'  
};

부분은 Model을 담당하고 있습니다. 데이터를 가지고 있지요.

var ex01_01 = new Vue({ 
    el: '#ex01_01', 
    data: model 
})

ex01_01 객체는 ViewModel로 Vue 객체의 el 속성은 HTML 요소를 data 속성은 모델 객체를 참조합니다. 즉, ex01_01 객체가 HTML 요소와 데이터를 참조하고 있기에 데이터가 변경되면 HTML 요소에 반영시킵니다.

간단한 코드만 보아도 모든 작업은 반응형으로 이루어 진다는걸 알 수 있습니다.

 

2. v-text, v-html 디렉티브

<div id="ex01_01">
    <h2>{{message}}</h2>
</div>

예제 HTML 요소에선 {{ }} 중괄호를 이용한 템플릿 표현식을 사용해 HTML DOM에 데이터를 랜더링하고 있습니다. 

이를 콧수염 표현식(Mustache Expression) 혹은 보간법(Interpolation)이라고 부르는데

항상 이와 같은 방식으로 선언적 랜더링을 하진 않습니다. 동일한 코드를 디렉티브를 이용해 표현해보겠습니다.

<div id="ex01_01">
    <h2 v-text="message"></h2>
</div>

결과는 이전 화면과 동일하게 화면이 출력됩니다. 

v-text와 비슷한 기능으로 v-html이 있습니다. v-html을 사용해도 위와 비슷하게 나오는데 이 둘의 차이점을 무엇일까요?

  • v-text, {{ }} : innerText 속성에 연결된다. 태크 문자열을 HTML 인코딩하여 나타내기 때문에 화면에는 태그 문자열이 그대로 나타낸다.
  • v-html : innerHTML 속성에 연결된다. 태그 문자열을 파싱하여 화면에 나타낸다.

 

v-text, v-html 각각 코드 작성한 뒤 실행하여 아래와 같이 개발자 도구를 열고 콘솔탭에서 모델 객체의 값을 변경해봅니다. (F12 혹은 CTRL + SHIFT + I로 열 수 있습니다.)

v-text

 

v-html

위 결과를 보아 v-text와 다르게 v-html은 HTML 인코딩, 디코딩을 수행하지 않는걸 알 수 있습니다.

보안상 v-html 디렉티브는 <script> 태그를 그대로 바인딩하여 XSS 공격 등에 취약하므로 v-text를 사용하는 것이 더 안전합니다.

 

3. v-bind 디렉티브

v-bind는 요소 객체의 속성들을 바인딩하기 위해 사용합니다.

<body>
    <div id="test">
        <input id="testId" type="text" v-bind:value="text">
        <br/>
        <img v-bind:src="imagePath" />
    </div>
    <script type="text/javascript">
        var model = {
            text: 'Hello World!',
            imagePath: "https://source.unsplash.com/random/150x150"
        };

        var test = new Vue({
            el: '#test',
            data: model
        })
    </script>
</body>

결과

매번 v-bind 작성이 번거롭다면 v-bind를 생략한 :value, :src만 작성해도 됩니다.

 

4. v-model 디렉티브

앞에서 살뵤본 디렉티브들은 모두 단방향 디렉티브입니다. HTML요소에서 값을 바꾸더라도 모델 객체의 값은 바뀌지 않습니다.

텍스트 필드 값을 변경하더라도 모델 값은 Hello World 그대로다.

그렇다면 모델 객체에 값을 반영하기 위한 양방향 바인딩으로 무엇을 쓰면 될까?

이때 사용할 수 있는 디렉티브가 v-model입니다.

<body>
    <div id="test">
        <input id="testId" type="text" v-model="text">
        <br/>
        <h2 v-html="text"></h2>
    </div>
    <script type="text/javascript">
        var test = new Vue({
            el: '#test',
            data: {
                text: ''
            }
        })
    </script>
</body>

v-model 디렉티브는 몇 가지 수식어를 지원합니다.

  • lazy: 입렵폼에서 이벤트가 발생할 때 입력한 값을 데이터와 동기화합니다. 예)<input type="text" v-model.lazy="name"/>
  • number: 숫자가 입력될 경우 number 타입의 값으로 자동 형변환되어 데이터 옵션 값으로 반영됩니다.
  • trim: 문자열의 앞뒤 공백을 자동으로 제거합니다.

 

5. v-show, v-if, v-else, v-else-if 디렉티브

v-if는 이름에서도 알 수 있든 조건에 부합되면 실행하는 기능을 가지고 있습니다.

비슷한 기능을 가진 것으로 v-show가 있는데 v-show와 v-if의 차이는 실제 렌더링 여부에 있습니다.

v-if는 조건에 부합되지 않으면 렌더링을 하지 않는 반면 v-show는 HTML에 랜더링한 후에 display 스타일 속성으로 화면에 보여줄지 여부를 결정합니다.

<body>
    <div id="level">
        점수 : <input type="text" v-model="score" />
        <br /> 등급 :
        <span v-if="score >= 3000">Gold</span>
        <span v-else-if="score >= 2000">Silver</span>
        <span v-else-if="score >= 1000">Bronze</span>
        <span v-else-if="score >= 0">Iron</span>
        <img v-show="score < 0" src="images/error.png" 
        style="width: 20px; height: 20; vertical-align: middle;">
    </div>
    <script type="text/javascript">
        var test = new Vue({
            el: '#level',
            data: {
                score: 0
            }
        })
    </script>
</body>

그렇기에 화면이 자주 변경되는 부분에선 v-if 디렉티브보단 v-show 디렉티브를 사용하는 것이 좋습니다.

'Vue' 카테고리의 다른 글

Vue.js 이벤트 처리  (0) 2021.02.25
Vue 인스턴스  (0) 2021.01.29
Vue.js 기타 디렉티브와 계산형 속성  (0) 2021.01.22
Vue.js 반복 렌더링 디렉티브  (0) 2021.01.12
Vue.js 시작하기  (0) 2020.12.21
댓글
공지사항