728x90

약관동의 체크박스는 보기에는 간단한데 의외로 체크해야할 로직이 많다. 전체 동의를 하면 하위 체크박스가 모두 선택 되어야 하고 하나가 풀리면 전체동의 체크박스도 풀려야 하고 필수 동의 체크값에 따라 하위 버튼도 disabled 가 해제 되어야 해서 체크박스가 선택 될때마다 하단 등록 버튼 상태를 변경하는 로직은 한번 정리해두는게 좋다. 

 

아래 예시는 하단에 확인 버튼의 disabled 속성을 isConfirmDisabled 변수에 담고 체크박스의 값에 따라 watch 에서 체크 하는 로직으로 구현 하였다. 체크박스 상태가 변경 될때마다 확인이 되어야 하는 부분이어서 watch 로 걸어 주는것이 조금 더 편리하다. vue 에서 watch 는 너무 많이 걸면 조건이 꼬이기도 하니까 주의할 필요가 있다.  

<template>
  <CheckField
    v-for="(term, index) in terms"
    :key="index"
    v-model="term.agreed"
    :class="'terms-item'"
    :label="term.text"
    :required-indicator="term.required"
    :optional-indicator="!term.required"
    :show-view-button="index !== 0"
    :toggle-checkbox="index === 3 ? toggleMarketingConsent : () => {}"
    @view="() => clickConsent(term.content, index)"
  />
  <button :disabled="isConfirmDisabled">확인</button>
</template>

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

const terms = ref([
  { agreed: false, text: '항목 1', required: true, content: '내용 1' },
  { agreed: false, text: '항목 2', required: true, content: '내용 2' },
  { agreed: false, text: '항목 3', required: false, content: '내용 3' },
  { agreed: false, text: '마케팅 동의', required: false, content: '내용 4' },
]);

const isConfirmDisabled = ref(true);

// 모든 항목의 동의 상태를 체크
watch(
  () => terms.value.map(term => term.agreed),
  (newAgreements) => {
    const allAgreed = terms.value[0]?.agreed && 
                      terms.value[1]?.agreed && 
                      terms.value[2]?.agreed;

    isConfirmDisabled.value = !allAgreed; // 모두 동의하지 않으면 버튼 비활성화
  },
  { immediate: true } // 컴포넌트 마운트 시 즉시 체크
);
</script>
728x90

+ Recent posts