본문 바로가기
Frontend/Vue

Vue: 템플릿 문법에 대해서 (1)

by 코딩쥐 2024. 10. 8.

Vue의 템플릿 문법은 HTML을 기반으로 하여, 데이터와 상호작용하며 동적으로 콘텐츠를 렌더링하는 역할을 한다.

 

Vue 기본 문법

  • createApp : Vue 애플리케이션을 시작하는 함수로, Vue 인스턴스를 생성한다. 
  • component 
    • data : 컴포넌트의 데이터를 반환하는 함수다. 
    • methods : 컴포넌트 인스턴스에 메서드를 추가한다. 
    • template : Vue 애플리케이션의 구조와 레이아웃을 정의한다. 
    • props : 부모 컴포넌트로부터 데이터를 전달받는다.    
  • mount : Vue 애플리케이션 인스턴스를 특정 DOM 요소에 연결하는 함수이다. 

템플릿 문법

데이터 바인딩

이중 중괄호를 사용하여 데이터를 바인딩 할 수 있다. 이중 중괄호 안의 데이터는 해당 컴포넌트 인스턴스의 속성 값으로 대체된다. 

  • {{데이터}}

 

디렉티브

Vue에서 사용되는 HTML 요소에 특별한 동작이나 기능을 부여하는데 사용되는 특수 속성이다.

디렉티브 설명
v-text 엘리먼트의 textContent를 업데이트 한다.
v-html 엘리먼트의 innerHTML을 업데이트 한다.
v-show 참-거짓을 기반으로 CSS 속성 중 display 를 전환한다. 초기 조건과 관계없이 항상 렌더링된다.
v-if 참-거짓에 따라 엘리먼트를 조건부로 렌더링한다.
v-else v-if 또는 v-else-if의 'else block'을 나타낸다. 
v-for 엘리먼트 또는 템플릿 블록을 여러번 렌더링한다. 
v-on 이벤트 리스너를 추가한다.  ( 단축문법 : @ )
v-bind HTML 요소의 속성을 Vue인스턴스의 데이터와 동적으로 바인딩한다. (단축문법 : : 혹은 .
v-model 양방향 데이터 바인딩을 생성한다. 주로 폼 컨트롤에서 사용된다.
v-slot 슬롯의 이름을 지정하거나 슬롯의 범위를 지정한다.
v-pre 컴파일 속도를 높이기 위해 템플릿 컴파일을 건너뛴다.
v-once 엘리먼트와 모든 컴포넌트를 한 번만 렌더링하고 이후 변경을 무시한다.
v-memo 메모이제이션을 위한 최적화 힌트를 제공한다.
v-cloak CSS 디스플레이를 none으로 설정하여 준비될 때까지 컴파일되지 않은 템플릿을 숨기는 데 사용한다.

 

v-text & v-html

v-text는 textContent를 v-html은 innerHTML을 업데이트 한다. 

  • v-text
    <태그 v-text="데이터"></태그>
  • v-html
    <태그 v-html="데이터"></태그>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <title>Document</title>
    <style>
        #app {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 15px;
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 데이터 바인딩 -->
        {{ text }}
        <!-- v-on : 이벤트 리스너 추가 -->
        <input type="text" @change="setValue($event)" />
        <button @click="setText">Set Value</button>
        <!-- v-text : textContent 업데이트 -->
        <p v-text="text1"></p>
        <!-- v-html : innerHTML 업데이트 -->
        <p v-html="text2"></p>
    </div>

    <script>
        const { createApp } = Vue;

        createApp({
            data() {
                return {
                    text: "",
                    text1: "v-text로 출력",
                    text2: "<p>v-hmtl로 출력</p>",
                    show: false,
                };
            },
            methods: {
                setValue(event) {
                    this.value = event.target.value;
                },
                setText() {
                    this.text = this.value;
                }
            }
        }).mount('#app'); 
    </script>
</body>

</html>

 

 

v-show & v-if & v-else 

v-show & v-if & v-else의 경우 특정 조건을 만족할 때만 콘텐츠를 렌더링 할 수 있는 디렉티브다. v-show는 초기 전 상태와 관계없이 렌더링을 시행하며 display를 전환한다. v-if와 v-else를 통해서 참-거짓에 따라 엘리먼트를 조건부로 렌더링한다. 자주 전환되어야 하는 경우에는 v-show를, 실행 중에 조건이 변경되지 않는 경우에는 v-if를 사용하면 리소스 절약을 할 수 있다 참-거짓에 따라 엘리먼트를 조건부로 렌더링한다.

  • v-show
    <태그 v-show="조건값"></태그>
  • v-if , v-else
    <태그 v-if="조건값"> true일 때 보임 </태그>

    <태그 v-else> v-if 조건값이 false일 때 보임 </태그>
  • v-else-if
    <태그 v-else-if="조건값">앞선 조건들이 모두 거짓으로 평가될 때 렌더링</태그>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <title>Document</title>
    <style>
        #app {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 15px;
        }
    </style>
</head>

<body>
    <div id="app">
         <!-- v-show : true/false에 따라 display 전환 -->
        <p v-show="show">v-show (초기 조건과 관계없이 렌더링)</p>
        <!-- v-if, v-else : 참/거짓에 따라 조건부 렌더링 -->
        <p v-if="show">v-if가 true일때 보임 (조건부 렌더링)</p>
        <p v-else>v-if가 false일때 보임</p>
        <button @click="toggleShow">Show toggle</button>
    </div>

    <script>
        const { createApp } = Vue;

        createApp({
            data() {
                return {
                    show: false,
                };
            },
            methods: {
                toggleShow() {
                    this.show = !this.show;
                }
            }
        }).mount('#app'); 
    </script>
</body>

</html>

 

v-for 

엘리먼트 또는 템플릿 블록을 여러번 렌더링한다. 목록이 늘어나면 새 항목이 렌더링된다. 

  • 배열
    <태그 v-for="(item, index) in 배열" :key="키로 설정할 값">{{item}}, {{index}}< / 태그>
배열 메서드 설명
push() 원소를 배열의 마지막 지점에 추가
pop() 배열의 마지막 원소 제거
shift() 배열의 첫 번째 요소를 제거
unshift() 원소를 배열의 시작 지점에 추가
splice() 특정 배열 위치 이후의 원소를 원하는 수만큼 삭제하거나 교체
sort() 값을 정렬
reverse() 배열 요소의 순서를 반대로 정렬
  • 객체
    <태그 v-for="(value, key) in 객체" :key="키로 설정할 값">{{value}}, {{key}}< / 태그>

해당하는 데이터(배열, 객체 등 가능)를 반복하면서 안에 들어 있는 항목(item)들과 해당 인덱스(index)를 가지고 와서 사용할 수 있다. key의 경우에는 Vue가 각 노드의 식별을 유지하고 재사용할 수 있게 하여 렌더링 성능을 향상시켜 주기 때문에, key를 작성하는 것이 좋다. 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <title>Document</title>
    <style>
        #app {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 15px;
        }
    </style>
</head>

<body>
    <div id="app">
        <ul>
            <!-- v-for : 엘리먼트를 여러번 렌더링함 -->
            <li v-for="element in arr" :key="element">{{element}}</li>
        </ul>
    </div>

    <script>
        const { createApp } = Vue;

        createApp({
            data() {
                return {
                    arr: ['Hello', 'Hola', '안녕'],
                };
            }}
        ).mount('#app'); 
    </script>
</body>

</html>

 

v-on

이벤트 리스너를 추가한다.  ( 단축문법 : @ ) 아래의 이벤트 수식어를 통해서 이벤트를 더 세밀하게 제어할 수 있다. 

이벤트 수식어 설명
.stop 이벤트의 전파를 막는다 (stopPropagation).
.prevent 기본 이벤트 동작을 방지한다 (preventDefault).
.capture 이벤트 캡처링 단계에서 리스너를 추가한다.
.self 이벤트가 해당 요소에서만 발생한다.
.once 이벤트가 한 번만 발생하도록 설정한다.
.passive { passive : true }를 설정한다.
*touch, wheel 등 일부 이벤트에서 동작을 최적화하여 스크롤 성능 향상

 

Vue.js에서는 키보드 입력과 마우스버튼을 처리하기 위해 입력키 수식어를 제공한다. exact 수식어를 사용하여 정확한 조합의 시스템 키가 눌렸을 때만 이벤트 핸들러가 실행되도록 할 수 있다 (예제 : v-on:click.ctrl.exact)

  • 키보드입력
    enter , tab, delete ("delete"키와 "Backspace"키 모두), esc, space, up, down, left, right, ctrl, alt, shift, meta
  • 마우스입력
    left, right, middle 
<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <style>
        #app>div {
            margin: 20px;
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- 해당 요소에서 직접 클릭한 경우에만 이벤트를 처리한다. -->
        <div @click="parentClicked">
            부모요소 (아무것도 적지않았을 때)
            <div @click="childClicked">자식요소</div>
        </div>

        <div @click.self="parentClicked">
            부모요소 (.self)
            <div @click="childClicked">자식요소</div>
        </div>

        <div @click="parentClicked">
            부모요소
            <div @click.stop="childClicked">자식요소 (.prevent) </div>
        </div>

        <div>
            <p>기본 이벤트 동작 방지</p>
            <form @submit.prevent="onSubmit">
                <input type="text" />
            </form>
        </div>

        <div>
            <p>ctrl+enter 눌러서 이벤트 시행</p>
            <input v-on:keyup.ctrl.enter="submitForm" />
        </div>
    </div>

    <script>
        const App = {
            methods: {
                parentClicked() {
                    alert('부모요소가 클릭되었습니다');
                },
                childClicked() {
                    alert('자식요소가 클릭되었습니다.');
                },
                onSubmit() {
                    alert('폼이 제출되었습니다.');
                },
                submitForm() {
                    alert('ctrl과 enter 눌러서 폼이 제출되었습니다.')
                }
            }
        }

        Vue.createApp(App).mount('#app')
    </script>
</body>

 

v-bind

HTML 요소의 속성을 Vue인스턴스의 데이터와 동적으로 바인딩한다. (단축문법 : : 혹은 . 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <title>Document</title>
    <style>
        #app {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 15px;
        }

        .textColor {
            color: lightblue;
        }

        #fontSize {
            font-size: 2rem;
        }
    </style>
</head>

<body>
    <div id="app">
        <!-- v-bind : HTML 요소 속성을 데이터와 바인딩 -->
        <a :href="link">코딩쥐의 티스토리</a>
        <p v-bind="attributes">v-bind를 통한 클래스와 아이디 설정</p>

    </div>

    <script>
        const { createApp } = Vue;

        createApp({
            data() {
                return {
                    link: "https://coding-ji.tistory.com",
                    attributes: { id: 'fontSize', class: 'textColor' }
                };
            }
        }).mount('#app'); 
    </script>
</body>

</html>

'Frontend > Vue' 카테고리의 다른 글

Vue: 템플릿 문법에 대해서 (2)  (0) 2024.10.17
Vue : 시작하기  (0) 2024.10.08