핵심 문법 (userInterface) - plgrim-hannah/vue-study GitHub Wiki

# 1. 선언적 렌더링

Vue.js의 핵심은 간단한 템플릿 구문을 사용하여 데이터를 선언적으로 DOM에 렌더링 할 수 있다는 것!

1) 텍스트 보간법(Interpolation)

  • 이중 중괄호 {{ }}, 일반 텍스트로 인식함

2) v-html

  • 엘리먼트의 innerHTML 출력함
  • Vue 템플릿 문법을 처리하지 않고 일반 HTML로 삽입됨
<template>
  <div>{{ rawHtml }}</div>
  <div>{{ rawHtml2 }}</div>
  <h1 v-html="rawHtml2"></h1>
</template>

<script>
export default {
  data() {
    return {
      rawHtml: "이것은 텍스트입니다.",
      rawHtml2: "<span style='color:red'>이것은 텍스트입니다.</span>",
    };
  },
};
</script>

<style lang="scss" scoped></style>

Untitled (6)

rawHtml 는 해당 컴포넌트 인스턴스 값으로 대체됨. rawHtml 속성이 업데이트될 때마다 변경됨.

rawHtml2는 이중 중괄호를 사용했기 때문에 텍스트로 인식해서 그대로 출력함

v-html property 를 이용하면 정상적으로 html 형식으로 출력 됨.

3) v-bind (Class, Style 바인딩)

  • 동적으로 하나 이상의 컴포넌트 속성 또는 표현식을 바인딩

  • class 또는 style 속성을 바인딩하는 데 사용되는 경우, v-bind는 배열 또는 객체와 같이 값을 추가할 수 있는 타입을 지원함

  • Class 바인딩

    v-bind: class (축약형은 :class), 객체로 바인딩 되며 동적으로 제어하기 위해서 사용함

  • Style 바인딩

    v-bind:style={}, 축약형 :style={} HTML 엘리먼트의 style 속성에 해당하는 JavaScript 객체에 대한 바인딩을 지원

<template>
  <div>{{ rawHtml }}</div>
  <div>{{ rawHtml2 }}</div>
  <h1 v-html="rawHtml2"></h1>

  <!-- <h2 v-bind:class="{ active: isActive }">클래스 바인딩 테스트입니다.</h2> -->
  <h2 :class="{ active: isActive }">클래스 바인딩 테스트입니다.</h2>
  <button @click="change">버튼</button>

  <!-- <h3 style="color: red; font-size: 24px">스타일 바인딩 테스트입니다.</h3> -->
  <h3 :style="{ color: fontColor, fontSize: fontSize + 'px' }">
    스타일 바인딩 테스트입니다.
  </h3>
</template>

<script>
export default {
  data() {
    return {
      rawHtml: "이것은 텍스트입니다.",
      rawHtml2: "<span style='color:red'>이것은 텍스트입니다.</span>",
      isActive: false,
      fontSize: 48,
      fontColor: "#888888",
    };
  },
  methods: {
    change() {
      this.isActive = !this.isActive;
    },
  },
};
</script>

<style scoped>
h2.active {
  color: green;
}
</style>

image

-> 클릭할 때마다 class가 바인딩 되면서 글자색이 바뀜!

Untitled (7)

-> Style 프로퍼티로 바인딩 됨


# 2.조건부 렌더링(v-if, v-show)

특정 조건에 따라 다른 결과물을 렌더링 함

  • v-if / v-else-if / v-else

    • 조건부로 블록을 렌더링 하는 데에 사용됨. 디렉티브 표현식이 [thruthy] (참 같은 값)일 때만 사용 ( = v-if 안에 담긴 조건문에 참인 경우에만, v-if가 선언된 레이아웃이 렌더링 된다는 걸 의미함 )

    • true /false 에서의 true만 해당 하는 게 아님. 조건문 자체가 참이 되면 됨 ( count 예시 참고)

  • v-show

    • v-if와 유사하나 v-show가 있는 엘리먼트는 DOM에 남음. display 속성만 전환됨.
    • v-if는 전환 비용이 더 높고, v-show는 초기 렌더링 비용이 더 높다. 자주 전환 시 v-show가, 실행 중에 조건이 변경되지 않으면 v-if가 권장됨
<template>
  <div>
    <div v-if="isVisible" class="red"></div>
    <div v-if="isVisible === true" class="blue"></div>

    <div v-else class="black"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isVisible: true,
    };
  },
};
</script>

<style scoped>
.red {
  width: 100px;
  height: 100px;

  background-color: red;
}
.blue {
  width: 100px;
  height: 100px;

  background-color: blue;
}
.black {
  width: 100px;
  height: 100px;

  background-color: black;
}
</style>

Untitled (8)

<script>
export default {
  data() {
    return {
      isVisible: false,
    };
  },
};
</script>

Untitled (9)

<template>
  <div>
    <!-- <div v-if="isVisible" class="red"></div>
    <div v-if="isVisible === true" class="blue"></div>

    <div v-else class="black"></div> -->

    <div v-if="count > 1" class="red"></div>
    <div v-else class="blue"></div>
    <button @click="count++">증가</button>
    <button @click="count--">감소</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isVisible: false,
      count: 0,
    };
  },
};
</script>

<style scoped>
.red {
  width: 100px;
  height: 100px;

  background-color: red;
}
.blue {
  width: 100px;
  height: 100px;

  background-color: blue;
}
.black {
  width: 100px;
  height: 100px;

  background-color: black;
}
</style>

Untitled (10) Untitled (11)

<template>
  <div>
    <div v-show="isVisible" class="red"></div>
    <div v-show="!isVisible" class="blue"></div>

    <div v-if="isVisible" class="black"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isVisible: false,
      count: 0,
    };
  },
};
</script>

<style scoped>
.red {
  width: 100px;
  height: 100px;

  background-color: red;
}
.blue {
  width: 100px;
  height: 100px;

  background-color: blue;
}
.black {
  width: 100px;
  height: 100px;

  background-color: black;
}

Untitled (12)

v-show 를 사용하면 조건이 거짓이라 출력 되지 않아도 DOM 요소가 남아있다.

반면에 v-if는 조건이 거짓이라 출력 되지 않으면 DOM 요소가 아예 사라진다. (주석 처리된 v-if 만 남아서 소스 위치만 표시됨)

# 3. 리스트 렌더링(v-for)

  • 배열 데이터 기반으로 동일한 구조의 UI를 반복 호출하는 기능을 말함
  • v-for 디렉티브를 사용하여 배열을 리스트로 렌더링할 수 있음
  • v-for 디렉티브는 item in items 형식의 특별한 문법이 필요함
  • v-for 객체 속성을 순회하는 데에 사용할 수 있음
  • 순회 순서 : 해당 객체를 Object.kyes()를 호출한 결과에 기반함
<template>
  <div>
    <li>{{ sampleArray[0] }}</li>
    <li>{{ sampleArray[1] }}</li>
    <li>{{ sampleArray[2] }}</li>
    <li>{{ sampleArray[3] }}</li>
  </div>
</template>

<script>
export default {
  data() {
    return {
      sampleArray: ["a", "b", "c", "d"],
    };
  },
};
</script>

<style scoped></style>

<li>{{ sampleArray[0] }}</li> 와 같은 반복적인 요소는 v-for로 개선 가능하다.

<template>
  <div>
    <li v-for="item in sampleArray">{{ item }}</li>
  </div>
</template>

<script>
export default {
  data() {
    return {
      sampleArray: ["a", "b", "c", "d"],
    };
  },
};
</script>

<style scoped></style>

Untitled (13)

⇒ 출력 결과는 위아래 모두 동일하다

<template>
  <div>
    <li v-for="item in sampleArray" :key="item">{{ item }}</li>
    <li v-for="user in otherArray" :key="user.id">
      {{ user.id }} / {{ user.name }}
    </li>
  </div>
</template>

<script>
export default {
  data() {
    return {
      sampleArray: ["a", "b", "c", "d"],
      otherArray: [
        { id: 0, name: "John" },
        { id: 1, name: "Kim" },
        { id: 2, name: "Lee" },
        { id: 3, name: "Park" },
      ],
    };
  },
};
</script>

<style scoped></style>

Untitled (14)

⇒ 객체를 순환할 때는 Object.key로 출력하기

:key (key 프로퍼티) 반드시 표시 해줘야한다. Vue.js 2.2버전부터는 필수가 되었다.

이유는 렌더링 시 부하와 관련이 있다.

만약 key 프로퍼티가 표시가 되어 있지 않는 경우 순서에 의존하여 렌더링이 된다.

10개의 데이터 중에 5번을 삭제할 경우, 다시 9개의 데이터가 다시 전체적으로 렌더링 되어 부하가 걸린다.

하지만 key 프로퍼티를 표시해주면 key 값만 찾아서 어떤 아이템이 삭제되었는지 식별하기 때문에 DOM 하나만 삭제되고 끝이 나서 부하가 굉장히 적어진다.

:key 는 고유한 값으로 설정해야 한다.

<template>
  <div>
    <li v-for="(item, index) in sampleArray" :key="item">
      {{ item }} / {{ index }}
    </li>
    <li v-for="(user, index) in otherArray" :key="user.id">
      {{ user.id }} / {{ user.name }} / {{ index }}
    </li>
  </div>
</template>

<script>
export default {
  data() {
    return {
      sampleArray: ["a", "b", "c", "d"],
      otherArray: [
        { id: 0, name: "John" },
        { id: 1, name: "Kim" },
        { id: 2, name: "Lee" },
        { id: 3, name: "Park" },
      ],
    };
  },
};
</script>

<style scoped></style>

=> index를 활용할 때는 v-for="(item, index) 문법으로 사용이 가능하다. (두번째 자리에 표기해준다)

단, index는 key 값으로 활용해서는 안된다. index는 고유한 값이 아닌 상황에 따라 달라질 수 있는 값이기 때문이다.

⚠️ **GitHub.com Fallback** ⚠️