단어 체크

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()를 타켓 단어와 인덱스 체크 값을 매개변수로 호출

댓글