[Vue.js] Component

2024. 7. 7. 20:54FE/Vue.js

  • Components Basics

 

 

Vue.js

Vue.js - The Progressive JavaScript Framework

vuejs.org

 


1. Component?

 

 

컴포넌트를 사용하면 UI를 독립적이고 재사용 가능한 단위로 분할하고 사용할 수 있다.

 

하나의 앱은 중첩된 컴포넌트의 트리로 구성된다.

 


가. Vite

 

Vite는 기존의 복잡한 설정 없이 빠르게 Vue 프로젝트를 시작하기 위해서 사용한다.

 

 

Vite

Vite, 차세대 프런트엔드 개발 툴

ko.vitejs.dev

 


나. vue file

 

SFC의 파일명은 항상 PascalCase로 작성한다. (첫 단어를 대문자로 시작하는 표기법)

 

단, 대소문자를 구분하지 않는 파일 시스템에서는 kebab-case로 작성한다.

 


다. SFC

<!-- vue file -->
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">당신은 {{ count }} 번 클릭했습니다.</button>
</template>

SFC (Single File Component)라고 하는 .vue 확장자를 사용해서 Vue 컴포넌트를 정의할 수 있다.

 

SFC는 별도의 빌드 단계가 필요하지만 많은 장점이 있다.

 

  • 친숙한 HTML, CSS 및 JavaScript 문법을 사용하여 모듈화 된 컴포넌트 작성
  • 본질적으로 사용 목적에 따라 구성됨
  • 런타임 컴파일 비용이 없는 사전 컴파일된 템플릿
  • 컴포넌트 범위 CSS
  • 컴포지션 API로 작업할 때 더욱 인체공학적인 문법
  • 템플릿과 스크립트를 교차 분석하여 컴파일 시간을 더욱 더 최적화
  • 템플릿 표현식을 지원하는 IDE의 자동 완성 및 유형 검사
  • 즉시 사용 가능한 핫 모듈 교체(Hot-Module Replacement: HMR) 지원

 

만약 빌드 방식을 사용하고 싶지 않다면, Vue 관련 옵션을 포함하는 순수 자바스크립트 객체로 컴포넌트를 정의할 수도 있다.

import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    return { count }
  },
  template: `
    <button @click="count++">
      당신은 {{ count }} 번 클릭했습니다.
    </button>`
  // DOM 내의 템플릿을 대상으로 할 수도 있습니다:
  // template: '#my-template-element'
}

JavaScript 문자열로 정의한 템플릿은 Vue가 그때그때 컴파일합니다.

 

1) Single Root Element

<!-- bad -->
<template>
    <h2>Heading</h2>
    <p>Paragraph</p>
    <p>Paragragh</p>
</template>

가독성, 스타일링, 명확한 컴포넌트 구조를 위해서 각 컴포넌트는 최상단 HTML요소를 가져야 한다.

 

<!-- good -->
<template>
    <div>
        <h2>Heading</h2>
        <p>Paragraph</p>
        <p>Paragragh</p>
    </div>
</template>

 


라. 컴포넌트 정의하기

 

SFC에는 하나의 컴포넌트를 정의하기 위해서 필요한 HTML, CSS, JS가 들어있다.

  • <template> : HTML → 뷰
  • <style> : CSS → 스타일
  • <script> : JS → 로직

 

<script setup>
import { ref } from 'vue'
</script>

<template>
  <div>

  </div>
</template>

<style scoped>

</style>
  • import { ref } from 'vue' : CDN 방식이 아닌 CLI 방식으로 전환되었다.
  • <script setup> : 컴포넌트의 setup() 함수에 해당.
  • <template><div> : 컴포넌트는 최상단 HTML 요소를 작성하는 것을 권장. (Single Root Element)
  • <style scoped> : 현재 컴포넌트에만 스타일이 적용된다.

 


3. 컴포넌트 사용하기

 

부모 컴포넌트에서 자식 컴포넌트 사용하는 방법에 대하여 알아보자.

 

 

Vue.js

Vue.js - The Progressive JavaScript Framework

vuejs.org

 

컴포넌트를 등록하는 2가지 방법이 존재한다.

 

전역적으로 등록하면 import 없이 사용할 수 있다. (물론 리소스가 낭비될 수 있다.)

 

아래 예시들은 기본적으로 로컬 등록의 자식 컴포넌트를 사용한다.

 

<script setup>
import ButtonCounter from './ButtonCounter.vue'
</script>

<template>
  <h1>아래에 자식 컴포넌트가 있습니다.</h1>
  <ButtonCounter />
  <ButtonCounter />
</template>

 

  • <script setup>
    : setup()안에서 선언되고 return되는 것과 같다.

  • import ButtonCounter from './ButtonCounter.vue'
    : 우선 사용할 컴포넌트를 import한다.
    : SFC에서는 네이티브 HTML 엘리먼트와 구별하기 위해 PascalCase 태그 이름을 사용하자.

  • <ButtonCounter />
    : 컴포넌트를 사용할 때마다 해당 컴포넌트의 새 인스턴스가 생성되기 때문에 각각의 독립성은 유지된다.

 


4. Props & Emit

 

 

[Vue.js] Props & Emit

Vue.jsVue.js - The Progressive JavaScript Frameworkvuejs.org Vue.jsVue.js - The Progressive JavaScript Frameworkvuejs.org 1. Props  Props: 컴포넌트에 등록할 수 있는 사용자 정의 속성.: 상위 컴포넌트가 하위 컴포넌트에게

ramen4598.tistory.com

 

 

 


5. Slot

 

<AlertBox>
  나쁜 일이 일어났습니다.
</AlertBox>

컴포넌트에 콘텐츠를 전달하고 싶을 때 Slot이 필요하다.

 

<!-- AlertBox.vue -->
<template>
  <div class="alert-box">
    <strong>이것은 데모용 에러입니다.</strong>
    <slot />
  </div>
</template>

<style scoped>
.alert-box {
  /* ... */
}
</style>
  • <slot /> : 전달받은 콘텐츠의 위치를 지정한다.

 

(다중 slot?)

 


6. Dynamic Component

 

<!-- currentTab이 변경되면 컴포넌트가 변경됩니다 -->
<component :is="tabs[currentTab]"></component>

컴포넌트 자체를 동적으로 변경하는 방법이다.

 

<component> 엘리먼트에 특별한 is 속성을 사용한다.

 

:is에 전달된 값은 …

  1. 등록된 컴포넌트의 이름 문자열
  2. 실제 가져온 컴포넌트 객체
  3. 일반 HTML 엘리먼트

 

여러 컴포넌트 간에 전환할 때, 다른 컴포넌트로 전환되면 기존의 컴포넌트가 마운트 해제된다.

 

<!-- Inactive components will be cached! -->
<KeepAlive>
  <component :is="activeComponent" />
</KeepAlive>

이때 내장된 <KeepAlive> 컴포넌트를 사용하여 비활성 컴포넌트를 "활성" 상태로 유지하도록 강제 캐싱할 수 있다.

 


'FE > Vue.js' 카테고리의 다른 글

[Vue.js] Vue-Router  (0) 2024.07.07
[Vue.js] Props & Emit  (0) 2024.07.07
[Vue.js] Watchers  (0) 2024.07.07
[Vue.js] 이벤트 핸들링  (0) 2024.07.07
[Vue.js] Lifecycle Hooks  (0) 2024.07.07