추가한 학습 목록을 배열에서 삭제하기를 구현합니다.
저번에 봤던것처럼 TheResource.vue 컴포넌트가 동적 컴포넌트로 연결되있기 때문에,
커스텀 이벤트를 발생시켜서 처리를 못하고, 직접 함수를 작성해야 합니다.
TheResources.vue
removeResource 함수와 provice에 deleteResource를 추가해주었습니다.
methods: {
setSelectedTab(tab) {
this.selectedTab = tab;
},
addResource(title, description, url) {
const newResource = {
id: new Date().toISOString(),
title: title,
description: description,
link: url
};
// 배열의 맨앞에 추가 (unshift) this.storedResources.unshift(newResource);
// 리소스를 추가할때마다 탭이 바뀌게 함
this.selectedTab = 'stored-resources';
},
// 리소스 삭제 함수
removeResource(resId) {
this.storedResources = this.storedResources.filter(res => res.id !== resId);
}
},
provide() {
return {
resources: this.storedResources,
addResource: this.addResource,
deleteResource: this.removeResource
};
},
LearningResource.vue
위에서 provide에 넣은 함수를 여기서 inject로 받아오고 props에 서id를 받습니다.
그 후 <base-button>
이 클릭 이벤트를 받아서 클릭 시 id를 찾아서 배열에서 삭제하게 됩니다.
<template>
<li>
<base-card>
<header>
<h3>{{ title }}</h3>
<base-button mode="flat" @click="deleteResource(id)">삭제</base-button>
</header>
<p>{{ description }}</p>
<nav>
<a :href="link">자료 보기</a>
</nav>
</base-card>
</li>
</template>
<script>
import BaseButton from "@/components/UI/BaseButton";
export default {
components: {BaseButton},
props: ['id', 'title', 'description', 'link'],
inject: ['deleteResource']
}
</script>
여기서 문제점은 내부 배열에서만 삭제되고 화면에선 삭제된 배열이 보이지 않는다는 것입니다.
provice에 storedResource가 포함되어 있는데 이에 따라 Vue가 provice를 실행하여 해당 컴포넌트를 생성합니다.
그 후 inject를 통해 this.storedResources 배열을 리소스가 필요한 모든 컴포넌트에 주입하죠.
그리고 저 값은 배열이고 값은 메모리에 저장됩니다.
리소스를 추가할 때와 같이 push나 unshift를 통해서 배열을 변경한다고 한다면?
기존에 입력했던 메모리 내 동일한 배열에도 변경 사항이 반영됩니다.
그에 따라 Vue가 해당 변경 사항을 인식할 수 있는거죠.
그리고 그 resource 키가 삽입된 모든 위치도 변경 사항을 인식합니다.
하지만, 위의 방법으로하면 this.storedResources를 새로운 배열로 덮어쓰게 됩니다.
그리고 이 새로운 배열은 다른 모든 컴포넌트에 입력되지 않습니다.
즉, 기존의 컴포넌트들은 아직도 기존의 배열만 인식하는 문제가 발생합니다.
이것을 해결하는 방법은 새로운 배열을 생성하지 말고 다른 방법을 사용하는 것입니다.
TheResource.vue
storedResource 배열에서 삭제하려는 리소스의 인덱스를 findIndex 함수를 이용해서 찾습니다.
그리고 splice 함수를 이용해서 특정 인덱스(resIndex)에 해당하는 리소스만 삭제하도록 합니다.
// 리소스 삭제 함수
removeResource(resId) {
const resIndex = this.storedResources.findIndex(res => res.id === resId);
this.storedResources.splice(resIndex, 1);
}
이렇게 하면 새로운 배열도 생성하지 않고 기존 배열을 조적하면서 연결된 모든 컴포넌트에 변경 사항을 전달하게 됩니다.
push와 unshift와 같은 개념입니다.
마지막으로, Dialog를 구현했었던 template에서 teleport 기능을 적용했습니다.
설명을 안쓴 이유는 너무 간단해서이고 DOM에서의 Dialog의 위치를 변경해서 오버레이되지 않게 적용했습니다.
이 어플리케이션을 만드는건 이게 마지막이지만, 여유가 생기면 백엔드 서버를 만들어 데이터를 저장하고,
더 다양한 기능 (커뮤니티, 실시간 채팅 등)을 구현한 후 배포할 계획이 있습니다.
지금 당장은 여기서 끝..
'📘 Frontend > Vue' 카테고리의 다른 글
Vue - Router (0) | 2023.08.08 |
---|---|
Vue - Native Fetch API를 이용한 HTTP Request 전송 (feat.Firebase) (0) | 2023.08.07 |
Vue - 학습 기록 앱 만들기 6 : Custom Dialog를 이용한 Validation (0) | 2023.08.05 |
Vue - 학습 기록 앱 만들기 5 : Input Form 구현 (0) | 2023.08.05 |
Vue - 학습 기록 앱 만들기 4 : 탭 간 전환 구현 (0) | 2023.08.05 |