가수면

[Vue] 기본 본문

Vue

[Vue] 기본

니비앙 2024. 5. 13. 03:24

기본 방식

리렌더링 조건

큰 조건은 리액트와 동일하다.

1. 상태값 변경

2. 부모 컴포넌트 리렌더링

3. props 변경

4. 강제 리렌더링

 

그러나 1번의 경우 리액트와 다른 점이 있다.

리액트의 경우 상태값이 변경되는 컴포넌트가 리렌더링이 발생하여 리렌더링을 방지하기 위해 memo, useMemo, useCallback 등을 이용해야하지만, Vue의 반응형 시스템은 상태 변경을 추적하여 필요한 부분만 리렌더링하므로 React처럼 명시적으로 리렌더링을 방지하는 메커니즘이 크게 필요하지 않다.

기본 형식

data에 상태 및 변수 정리

<template>
  <Navbar />
  <h1>영화정보</h1>
  <div>
    <h3 class="bg-yellow" :style="textRed">{{ title }}</h3>	// :속성명="데이터"
    <p>개봉: {{ year }}</p>
    <p>장르: {{ category }}</p>
  </div>
</template>

<script lang="ts">
import Navbar from "./components/Navbar.vue";
export default {
  name: "App",		// 컴포넌트 이름
  data() {		// 상태 변수들
    return {
      title: "노량",
      year: 2023,
      category: "액션, 드라마",
      textRed: "color: red",
    };
  },
  components: {		// 불러올 컴포넌트들
    Navbar,
  },
};
</script>

<style scoped>
.bg-yellow {
  background-color: yellow;
}
</style>

반복문 및 조건문

<div v-for="(item, i) in 데이터" :key="i"> 형식으로 컴포넌트 반복문 사용

<div v-if="boolean값"> 형식으로 컴포넌트 조건문 사용

<template>
  <h1>영화정보</h1>
  <div v-for="({ title, year, category }, i) in data" :key="i">
    <h3 class="bg-yellow" :style="textRed">{{ title }}</h3>
    <p>개봉: {{ year }}</p>
    <p>장르: {{ category }}</p>
  </div>
</template>

<script lang="ts">
export default {
  name: "App",
  data() {
    return {
      data: [
        {
          title: "노량",
          year: 2023,
          category: "액션, 드라마",
        },
      ],
      textRed: "color: red",
    };
  },
};
</script>

<style scoped>
.bg-yellow {
  background-color: yellow;
}
</style>
  <div class="modal" v-if="isModal">
    <div class="inner">
      <h3>Detail</h3>
      <p>영화 상세정보</p>
      <button @:click="toggleModal">닫기</button>
    </div>
  </div>

조건부 스타일링

<div class="event" :class="{ show: isOpen }"> 형식으로 조건부 클래스 처리

<div class="event" :class="{ show: isOpen }">

<style>
.event {
  background: #444;
  ...
}

.show {
  display: flex;
}
</style>

이벤트 및 함수

<button v-on:이벤트명="실행코드" or @:이벤트명="실행코드"> 형식

methods에 함수 정리

<template>
  <h1>영화정보</h1>
  <div v-for="({ title, year, category, like }, i) in data" :key="i">
    <h3 class="bg-yellow" :style="textRed">{{ title }}</h3>
    <p>개봉: {{ year }}</p>
    <p>장르: {{ category }}</p>
    <button @:click="increaseLike(i)">좋아요</button> <span>{{ like }}</span>
  </div>
</template>

<script lang="ts">
import data from "./assets/movies.ts";
export default {
  name: "App",
  data() {
    return {
      isModal: false,
      data,
      textRed: "color: red",
    };
  },
  methods: {	// 함수 정의
    increaseLike(i: number) {
      this.data[i].like += 1;
    },
  },
};
</script>

input 이벤트

 @input="inputText = $event.target.value" 형식으로 사용 가능한데,

뷰 문법을 사용하면 v-model="inputText" 이처럼 사용할 수 있음

@change="inputText = $event.target.value" 입력 후 엔터키를 치거나 확인 버튼을 누를 때 처리 됨

<template>
  <div class="search-box">
    <input type="search" 
    @input="inputText = $event.target.value"	// 셋 중 하나
    v-model="inputText"				// 셋 중 하나
    @change="handleInputChange"			// 셋 중 하나
    placeholder="검색어 입력" />
    <button>검색</button>
  </div>
  <p>{{ inputText }}</p>
</template>

<script lang="ts">
export default {
  name: "SearchBarComponent",
  data() {
    return {
      inputText: "",
    };
  },
  methods: {
    handleInputChange(event: Event) {
      const target = event.target as HTMLInputElement;
      if (target) {
        this.inputText = target.value;
      }
    },
  },
  },
};
</script>

watch로 변수 실시간 검사

검사할 변수명(변경값, 이전값) {

  로직

}

<script lang="ts">
export default {
  name: "SearchBarComponent",
  data() {
    return {
      inputText: "",
    };
  },
  watch: {
    inputText(name) {
      if(name !== "노량") {
        alert('해당하는 영화가 없습니다');
      }
    }
  }
};
</script>

그외 이벤트

<script lang="ts">
export default {
  name: "testComponent",
  mounted() {},		// 마운트될 때
  unmounted() {},	// 언마운트될 때
};
</script>

Props

부모 컴포넌트에서 전달

:속성명="데이터"를 통해 속성 전달 (단방향 바인딩)

@이벤트명="함수 or 함수($event - 파라미터)"를 통해 함수 전달1

 

자식 컴포넌트에서 사용

props를 통해 자식 컴포넌트에서 props 정의

$emit('이벤트 명' or '이벤트 명', 인자)를 통해 함수 사용

// 부모 컴포넌트

  <Movies
    :data="data"
    @openModal="
      isModal = true;
      selectedMovieIndex = $event;
    "
    @increaseLike="increaseLike($event)"
  />
<template>
  <div class="container">
    <h1>영화정보</h1>
    <div v-for="({ title, year, category, like, imgUrl }, i) in data" :key="i" class="item">
      <figure>
        <img :src="imgUrl" :alt="title" />
      </figure>
      <div class="info">
        <h3 class="bg-yellow" :style="textRed">{{ title }}</h3>
        <p>개봉: {{ year }}</p>
        <p>장르: {{ category }}</p>
        <button @:click="$emit('increaseLike', i)">좋아요</button>
        <span>{{ like }}</span>
        <p>
          <button @:click="$emit('openModal', i)">상세보기</button>
        </p>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { PropType } from "vue";
import { Movie } from "../assets/movies";

export default {
  name: "MoviesComponent",
  data() {
    return {
      textRed: "color: red",
    };
  },
  props: {
    data: Array as PropType<Movie[]>,
    isModal: Boolean,
    selectedMovieIndex: Number,
  },
};
</script>

양방향 바인딩

v-model:visible="상태값"을 통해 양방향 바인딩 가능 (props 이름이 visible로 설정된다. :visible을 설정하지 않으면 기본 props 이름으로 modelValue가 넘어감)

v-model은 내부적으로 :modelValue와 @update:modelValue을 결합한 것으로 update:modelValue 이벤트를 사용한다.

기타 Vue 문법

v-html="변수명"  // 문자열을 html로 읽을 수 있게 함

<h2 v-html="title"></h2>
...
const title = "Hello,<br> I'm Michael Kwon";

환경 변수

const API_KEY = import.meta.env.VITE_변수명;

'Vue' 카테고리의 다른 글

Vuetify 컴포넌트 자식 요소의 스타일 커스텀하는 방법  (0) 2024.08.26
[Vue] 심화  (0) 2024.05.25
[Vue] 전역 상태 관리  (0) 2024.05.16
[Vue] Router  (0) 2024.05.16
[Vue] Composition API 방식  (0) 2024.05.13
Comments