Vue3 Data Method와 Rendering Directives

2024-01-01 13:12:06

#Vue3

Vue의 data() method

  • data method가 반환하는 객체는 모두 proxy로 래핑됩니다.
Vue.createApp({
    name : "App",
    data() {
        return {
            contracts : [
            ] // ES6 Proxy 객체로 Wrapping됨.
        };
    },
})
  • 위 contracts 배열은 proxy 로 래핑되서 반환되며, 이때 배열의 데이터를 변경하는 method들(push(),splice(),sort())도 같이 래핑하고 있습니다. 즉 배열의 데이터가 변경되면 Watcher에게 변경을 알려서 다시 렌더링이 일어나도록 합니다.
  • 떄문에 데이터를 변경하고자 하면 항상 Proxy 객체를 통해서 변경시켜야 합니다. Vue 인스턴스 외부에서 배열을 직접 변경하면 Vue에서 제공하는 반응성이 동작하지 않습니다.

Vue Rendering 관련 디렉티브

  1. v-text 디렉티브 사용 : HTML 태그를 escape 처리하여 문자열 그대로 노출합니다.
  • 내부적으로 innerText 속성에 연결됩니다.
<div id="app">
    <h2 v-text="message"></h2>
</div>
  1. v-html 디렉티브 사용 : HTML 태그를 파싱해서 노출합니다.
  • 태그가 치환되어 노출되며, 내부적으로 innerHtml 속성에 연결됩니다.
<div id="app">
    <h2 v-html="message"></h2>
</div>
  1. v-bind 디렉티브 사용 : DOM의 특정 속성값을 데이터 바인딩할 수 있습니다.
  • v-bind:value 는 :value와 같이 v-bind 디렉티브를 생략하고 사용가능합니다.
  • v-bind 디렉티브는 단방향 데이터 바인딩입니다. 즉 model값의 변경이 View에 바인딩되지만, View의 변경이 model에 바인딩되지는 않습니다.
<input type="text" :value="message" />
<img v-bind:src="imgPath" />
// ---
const model = {
            message : "hello Vue3!",
            imgPath : "https://cdn.pixabay.com/photo/2016/03/02/13/59/bird-1232416_1280.png",
        };
const vm = Vue.createApp({
    name : "App",
    data(){
        return model;
    }
})
  1. v-model 디렉티브 : v-bind와 유사한 역할을 수행하나, 양방향 데이터 바인딩입니다.
  • 아래 input 에 사용자가 값을 입력하면 model의 message값 역시 변경됩니다.
<input type="text" v-model="message">
  • v-model을 통한 양방향 데이터 바인딩은 CheckBox,Select,Radio Button에도 적용이 가능합니다.
<div id="app">
    <div>
        <h2>개발자</h2>
        <input type="checkbox" id="devA" value="A" v-model="developer">
        <label for="devA">찬수</label>
        <input type="checkbox" id="devB" value="B" v-model="developer">
        <label for="devB">준영</label>
        <input type="checkbox" id="devC" value="C" v-model="developer">
        <label for="devC">강호</label>
    </div>
    <div>
        <h3>Domain</h3>
        <select v-model="domain">
            <option value="C1">의료</option>
            <option value="C2">금융</option>
            <option value="C3">커머스</option>
        </select>
    </div>
</div>

 <script type="text/javascript">
    const vm  = Vue.createApp({
        name : "App",
        data() {
            return {
                developer : [],
                domain : "",
            };
        }
    }).mount("#app")
</script>

Modifier(수식어)

  • Modifier는 디렉티브에 기능을 추가하는 Vue.js 디렉티브의 문법 요소로 v-model 디렉티브에는 다음과 같은 디렉티브를 사용할 수 있습니다.
  • 예를 들어 number 디렉티브는 input에 입력되는 사용자 입력값중에 형변환이 가능한 부분만 숫자로 치환하는 역할을 수행합니다.
<input type="text" v-model.number="num">
  • 한번에 여러 개의 디렉티브를 적용할 수 있습니다. (v-model.number.trim)

조건 렌더링 디렉티브

  • 특정 조건에 따라 화면에 보여줄지 말지를 결정하는 디렉티브입니다.
  1. v-show
  • 렌더링은 수행하지만, display: none; 으로 화면상에서는 보이지 않습니다.
<p v-show="hasChild > 0">father</p>
  1. v-if
  • v-show와 다르게 렌더링 자체가 수행되지 않습니다.
  • v-else-if, v-else로 분기를 지어서 렌더링될 DOM을 결정할 수 있습니다.
<p v-if="hasChild > 0">father</p>
<p v-else-if="hasChild == 0 ">solo</p>
<p v-else>error</p>

반복 렌더링 디렉티브

  • 말그대로 기본 for문과 유사하다. 단 객체의 경우는 Key(속성)도 같이 가져올 수 있습니다.
// array
<div v-for="(name,index) in names" >
    <p>{{ name }}</p>
</div>
// object
<div v-for="(v,k,index) in names">
    <p>{{ k }} : {{ v }}</p>
</div>
  • template 태그를 활용하면 v-for 에 사용되는 반복문 변수들을 그룹으로 묶어 사용이 가능합니다.
<template v-for="(contract,index) in contracts">
    <tr>
        <td>{{ contract.name }}</td>
        <td>{{ contract.age  }}</td>
    </tr>
    <hr v-show="index % 2 === 0">
</template>
  • DOM요소를 변경하는 케이스가 존재한다면, key 속성을 추가하면 변경되는 DOM 요소에 대해서만 렌더링을 수행합니다. 즉 변경되지 않은 요소에 대해서는 렌더링을 수행하지 않으므로 더 좋은 성능을 낼 수 있습니다.

    • key에는 항상 고유한 값만을 부여해야만 의도한 성능 향상 효과가 일어날 수 있습니다.
    • key값이 바뀌게 되면 모두 다시 Rendering을 수행되기 떄문에 반복문의 index를 key로 두면 안되고, 데이터베이스의 PK와 같은 고유한 값을 주어야만 변경 요소에 대해서만 렌더링하는 작업과 요소의 위치만 변경해주는 reflow 작업만을 수행합니다.
    • 가급적 key 특성을 부여하고, index가 아닌 고유한 값을 사용해야 합니다.

기타 디렉티브

  1. v-pre 디렉티브 : HTML 요소에 대해 컴파일을 수행하지 않습니다. 즉 템플릿 문자열 그대로 출력됩니다.
<span v-pre>{{message}}</span>
  1. v-once 디렉티브 : 최초에만 렌더링을 수행합니다. 이후에 데이터가 변경되도 렌더링을 수행하지 않습니다.
<span v-once>{{message}}</span>
  1. v-cloak : 화면 초기에 컴파일 되지 않은 템플릿은 출력되지 않도록 방지해주는 역할을 수행하는 디렉티브입니다.
<style>
    [v-cloak] {
        display: none;
    }
</style>

<div id="app" v-cloak>
    {{ message }}
</div>

Dynamic Argument

  • 디렉티브에 연결하고자 하는 특성의 이름을 속성에 바로 연결할 수 있도록 해주는 문법입니다.
  • [] 안에서는 연산식이나, 대문자를 사용할수 없습니다.
<div v-bind:[속성명] = "속성값"></div>
<div :[속성명] = "속성값"></div>
<div v-on:[이벤트명] = "이벤트 핸들러"></div>
<div @[이벤트명] = "이벤트 핸들러"></div>

예시를 들면 아래와 같이 model의 속성명,값을 각각 매핑시켜서 사용할 수 있습니다.

<div id="app" v-cloak>
    <img v-bind:[image.srcattr]="image.src" :[image.titleatrr]="image.title"/>
</div>
//Vue 인스턴스
data() {
  return {
    image: {
      srcattr: "src",
      src:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTbmy5coC0UlI8Z_2hPuBzTJpB6b6Y7ST3zFQ&usqp=CAU",
      titleatrr: "title" ,
      title: "cs"
    }
  }
}
  • 다음과 같이 여러개의 data를 한번에 속성으로 전달하고자 하는 경우 간단히 특성이름없이 바인딩할 수 있습니다.
<img v-bind="image"/>
//Vue 인스턴스
data() {
  return {
    image: {
      src:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTbmy5coC0UlI8Z_2hPuBzTJpB6b6Y7ST3zFQ&usqp=CAU",
      title: "cs"
    }
  }
}
프로필 이미지
@chani
바둑 좋아하는 개발자의 의미있는 학습 기록을 위한 공간입니다.

댓글

이 게시글에 대한 의견을 공유해주세요!

댓글