프론트엔드/뷰(Vue)

Vue3 Composition API와 기초 문법 다뤄보기(2)

xhakxh135 2024. 3. 22. 10:49
반응형
SMALL

Vue3 Composition API와 기초 문법 다뤄보기(1) 에 이어서 나머지 문법을을 다뤄보고자 한다.

 

6. 조건부 렌더링

v-if는 엘리먼트를 조건부로 렌더링 하기 위해 사용된다.

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

const awesome = ref(true)

function toggle() {
 awesome.value=!awesome.value
 //토글 작업 시 사용코드 이다.
}
</script>

<template>
  <button @click="toggle">토글 버튼</button>
  <h1 v-if="awesome">Vue는 굉장해! 엄청나!</h1>
  <h1 v-else>오 안돼 😢</h1>
</template>

 

v-if와 v-else가 있는 태그는 위 아래로 붙어 있어야 동작한다.


7. 리스트 렌더링

v-for을 사용해서 자료 배열을 렌더링 할 수 있다.

<ul>
  <li v-for="todo in todos" :key="todo.id">
    {{todo.text}}
  </li>
</ul>

 

v-for 사용시에는 고유의 key값을 꼭 넣어줘야한다.

key를 사용하면 vue가 각 li를 정확하게 이동시켜 배열에서 해당 객체의 위치와 일치하게 할 수 있다.

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

// 각 할 일에 고유한 ID 부여
let id = 0

const newTodo = ref('')
const todos = ref([
  { id: id++, text: 'HTML 배우기' },
  { id: id++, text: 'JavaScript 배우기' },
  { id: id++, text: 'Vue 배우기' }
])

function addTodo() {
  todos.value.push({id:id++, text:newTodo.value})
  //자료 배열에서 변경 메서드를 호출한다.
  newTodo.value = ''
}

function removeTodo(todo) {
  todos.value = todos.value.filter((t) => t !== todo)
  //배열을 새 배열로 교체한다.
 }
</script>

<template>
  <form @submit.prevent="addTodo">
    <input v-model="newTodo" required placeholder="new todo">
    <button>할 일 추가</button>
  </form>
  <ul>
    <li v-for="todo in todos" :key="todo.id">
      {{ todo.text }}
      <button @click="removeTodo(todo)">X</button>
    </li>
  </ul>
</template>

                                                                                                                                                                                                 

                                                                                                                                                                                                 


8. 계산된 속성, computed

computed는 반응 데이터 소스를 기반으로 .value를 계산하는 계산된 ref를 만들 수 있다.

계산된 속성은 의존성이 변경되면 자동으로 업데이트한다.

 

7.리스트 렌더링 예제 코드에 이어서 계산된 속성 filterTodos를 추가하고,

완료된 항목 숨기기 버튼을 누르면 완료한 할 일은 즉시 숨겨져야 한다.

 

<script setup>
import { ref, computed } from 'vue'

let id = 0 //id 값 0 부터 시작

const newTodo = ref('') //반응성 추가
const hideCompleted = ref(false) //완료 숨김 초깃값 false

const todos = ref([
  { id: id++, text: 'HTML 배우기', done :true },
  { id: id++, text: 'JavaScript 배우기', done :false },
  { id: id++, text: 'Vue 배우기', done :false }
]) // todos 리스트업

const filteredTodos = computed(() => {
  return hideCompleted.value
  ? todos.value.filter((t) => !t.done)
  : todos.value
}) 
//(값이 true일 때는 todos배열에서 done 속성이 false인 객체들만 필터링 해서 반환, 
//false일 때는 모든 작업들 반환)
//여기서 (t)는 todos의 목록들을 나타낸다.
//!t.done은 해당 할 일 항목이 완료되지 않았다는 것을 의미 false
//filter((t) => !t.done)는 완료여부 확인체크용

function addTodo() {
  todos.value.push({id:id++, text:newTodo.value, done:false})
  newTodo.value = ''
}

function removeTodo(todo) {
  todos.value = todos.value.filter((t) => t !== todo)
}
</script>

<template>
  <form @submit.prevent="addTodo">
    <input v-model="newTodo" required placeholder="new todo">
    <button>작성하기</button>
  </form>
  <ul>
    <li v-for="todo in filteredTodos" :key="todo.id">
      <input type="checkbox" v-model="todo.done">
      <span :class="{ done : todo.done }">{{todo.text}}</span>
      <button @click="removeTodo(todo)">X</button>
    </li>
  </ul>  
  <button @click="hideCompleted = !hideCompleted">
    {{ hideCompleted ? 'show all' : 'hide completed' }}
  </button>
    
</template>

<style>
 .done {
   text-decoration : line-through;
 }
</style>

새로운 할 일 등록
hide completed 클릭 시 체크박스로 완료 표기 된 리스트 숨기기

 


9. 생명주기와 참조

DOM을 수동으로 작업해야 하는 경우가 있다. 이럴땐 ref 를 사용해주면 된다.

참조에 접근하려면 이름이 일치하는 ref를 선언해주면 된다.

 

ref는 null값으로 초기화한다. script setuo 실행 시 해당 엘리먼트가 아직 존재하지 않기 때문이다.

템플릿 참조는 컴포넌트가 마운트(onMounted) 된 후에만 접근할 수 있다.

 

<script setup>
import { ref, onMounted } from 'vue'

const pElementRef = ref(null)

onMounted(() => {
  pElementRef.value.textContent= '마운트 되었어요';
 }
)
</script>

<template>
  <p ref="pElementRef">안녕</p>
</template>

 


10. watch

watch()는 말 그대로 지켜보다가 ref가 실시간으로 변하는 것을 감지 할 수 있다.

computed와 유사하지만 부가적인 동작에 더 많이 사용된다. 

무언가를 초기화 하거나 특정 데이터가 변경되거나 구성 요소가

더 이상 사용되지 않을 때 정리해야 하는 경우 watch를 사용한다.

computed가 주로 동기로 값을 리턴한다면 watch는 비동기로 처리되고 값을 리턴하지 않는다.

watch :{
  함수명(새로운 값, 이전 값){
  //...
  }
}

 

아래 예시코드1)는 foo의 값이 변경 될 때 마다 newValue값을 활용할 수 있다.

<script setup>
  import {ref, watch} from 'vue'
  const foo = ref('')
  
  watch(foo, (newValue) => {
    consol.log(`foo의 값 : ${newValue}`);
  })

</script>

 

 

예시코드2)

<template>
  <div>
    <p>Counter:{{counter}}</p>
    <button @click="increment">카운트 버튼</button>
  </div>
</template>

<script setup>
  import {ref, watch} from 'vue';
  
  const counter = ref(0);
  
  watch(counter, (newValue, oldValue) => {
    console.log('${oldValue}에서부터 ${newValue} 카운터 변경');
  })
  <!--
      watch에서 첫번째 매개변수는 변경 사항을 감시하려는 값이나 표현식이고, 
      두번째 매개변수는 감시된 값이 변경될 때 실행되는 콜백함수 이다.
      -->
  
  const increment = () => {
    counter.value++;
  }
</script>

                                                                                                    

기본 틀은 다음과 같다.

watch(watchExpression, callback, options?)

 

-watchExpression : 반응형 개체에 대한 참조나 감시할 값을 반환하는 함수가 들어간다. 변경사항을 추적하고 변경 시 콜백을 트리거한다.

- callback : 관찰한 표현이 바뀔 때 마다 호출되는 함수이다. 위 예시코드2) 에서 newValue, oldValue 라는 두개의 인수를 받는다. 이 함수 내에서 값이 변경 될 때 수행할 작업을 정의할 수 있다.

- options : 설정 시 콜백을 주는 즉시 실행해야 하는지 여부를 나타내는 감시자에 대한 추가옵션이 포함되어 있다.

                                                                                                                                                                                               


11. 컴포넌트

단일컴포넌트가 아닌 중첩된 컴포넌트를 활용할 수 있다.

상위 컴포넌트는 다른 컴포넌트를 템플릿의 하위 컴포넌트로 랜더링 할 수 있다.

 

하위컴포넌트를 가져오는 기본적인 구조는 아래와 같다.

<!-------------App.vue------------------>
<script setup>
  import ChildComp from './ChildComp.vue'
</script>

<template>
  <ChildComp />
</template>
<!-------------App.vue------------------>

<!------------ChildComp.vue-------------->
<template>
  <h1>자식 컴포넌트 입니다.</h1>
</template>
<!------------ChildComp.vue-------------->

 

 

 

글이 길어져서 추가 문법(props, emit 등)에 대한 내용은 3편에서 다뤄보도록 하겠다.

 

 

 

참고 : https://ko.vuejs.org/

반응형
LIST