단어 체크
2023년 3월 10일
intro
외운 단어를 지우기는 애매하고 외우지 않은 단어와는 차이를 두고 싶을 때 체크하는 기능을 구현.
구현할 기능 미리보기
code
store/Main.js
store/Main.js
import { ref } from 'vue';
import { defineStore } from 'pinia';
import { useStorage } from '@vueuse/core';
import { useModalStore } from './Modal';
export const useMainStore = defineStore('main', () => {
const modalStore = useModalStore();
const localWords = useStorage('mapWords', new Map(), localStorage);
const wordArr = ref([]);
function getTimeAndTimestamp() {
const date = new Date();
const nowTime = `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}`;
const timestamp = date.getTime();
return { date, nowTime, timestamp };
}
function wordArrUpdate() {
const localWordsToArr = Array.from(localWords.value, (item) => {
return { ...item[1] };
} );
wordArr.value = [...localWordsToArr].reverse();
}
// init: localStorage에 있는 단어들 set
function setWordDic() {
wordArrUpdate();
}
// word add
function wordAdd(word, means) {
const { nowTime, timestamp } = getTimeAndTimestamp();
const item = { word, means: means.toString(), timestamp, time: nowTime, check: false };
// 이미 단어가 존재하면 지웠다가 저장
if (localWords.value.has(word)) {
localWords.value.delete(word);
}
localWords.value.set(word, item);
wordArrUpdate();
modalStore.modalExit();
}
// word check
function wordCheck(targetWord, ch, index) {
wordArr.value[index].check = ch;
const checkedWord = localWords.value.get(targetWord);
checkedWord.check = ch
localWords.value.set(targetWord, checkedWord);
}
return { wordArr, setWordDic, wordAdd, wordCheck}
});
function wordCheck(targetWord, ch, index)
: 단어 체크 기능을 위해 추가된 함수, 입력받은index
를 이용해wordArr
에 저장된targetWord
의 check의 값을ch
로 변경. 또한 객체 Map 형태인localWord
에 저장된targetWord
도 get, set을 이용해 갱신
components/WordCard.vue
components/WordCard.vue
<script setup>
import { Icon } from '@iconify/vue';
import { useMainStore } from '../stores/Main';
import { ref } from 'vue';
const props = defineProps({
word: String,
means: String,
check: Boolean,
index: Number,
})
const mainStore = useMainStore();
const word = ref(props.word);
const means = ref(props.means);
const check = ref(props.check);
const index = ref(props.index);
function checkBtnClick() {
check.value = !check.value;
mainStore.wordCheck(word.value, check.value, index.value);
}
</script>
<template>
<div class="flex flex-col">
<div class="flex gap-x-1">
<!-- check Icon -->
<button>
<Icon v-if="check === false" class="flex items-center" @click="checkBtnClick" icon="carbon:checkbox" width="37" height="37"></Icon>
<Icon v-else class="flex items-center" @click="checkBtnClick" icon="carbon:checkbox-checked" width="37" height="37"></Icon>
</button>
<!-- word -->
<span class="card_word" :class="{ wordcheck_active: check }" >{{ word }}</span>
</div>
<!-- mean -->
<div :class="{ wordcheck_active: check }">
<li v-for="mean in means.split(',')" :key="mean" class="card_content">
{{ mean }}
</li>
</div>
</div>
</template>
<style scoped>
.wordcheck_active {
@apply opacity-60 line-through decoration-2;
}
</style>
- 체크 값이 true 면 클래스 wordcheck_active가 존재하게 되는 객체 구문으로 클래스를 바인딩
function checkBtnClick()
: 체크 아이콘을 누르면 체크 값이 토글 되며 Main 스토어의checkBtnClick()
를 타켓 단어와 인덱스 체크 값을 매개변수로 호출