Vue.js 를 배워보자

Vue.js에서 watch로 버튼과 그리드의 disabled 상태 동적 제어하기

_Blue_Sky_ 2025. 3. 16. 22:24
728x90

 

Vue.js에서 반응형 데이터와 watch를 사용하면 데이터 변화에 따라 UI 요소의 상태를 쉽게 제어할 수 있습니다. 이번 글에서는 action 값에 따라 버튼과 그리드의 disabled 속성을 동적으로 업데이트하는 방법을 알아보겠습니다. reactive 객체를 활용하고, watch로 상태를 감시하며, 실제 버튼과 그리드에 바인딩하는 과정을 단계별로 설명합니다.

 

요구사항
  • 초기 상태: action: 'normal'
    • disabledGrid: false, disabledNew: false, disabledEdit: false
    • disabledSave: true, disabledCancel: true
  • action'insert' 또는 'edit'일 때:
    • disabledGrid: true, disabledNew: true, disabledEdit: true
    • disabledSave: false, disabledCancel: false
  • action'save' 또는 'cancel'일 때:
    • disabledGrid: false, disabledNew: false, disabledEdit: false
    • disabledSave: true, disabledCancel: true
구현 코드
<script setup>
import { reactive, watch } from 'vue'

// 반응형 객체 정의
const myCompo = reactive({
  action: 'normal',
  disabledGrid: false,
  disabledNew: false,
  disabledEdit: false,
  disabledSave: true,
  disabledCancel: true
})

// action 변화 감시
watch(
  () => myCompo.action,
  (newAction) => {
    if (newAction === 'insert' || newAction === 'edit') {
      myCompo.disabledGrid = true
      myCompo.disabledNew = true
      myCompo.disabledEdit = true
      myCompo.disabledSave = false
      myCompo.disabledCancel = false
    } else if (newAction === 'save' || newAction === 'cancel') {
      myCompo.disabledGrid = false
      myCompo.disabledNew = false
      myCompo.disabledEdit = false
      myCompo.disabledSave = true
      myCompo.disabledCancel = true
    } else {
      // 기본 상태 (normal 등)
      myCompo.disabledGrid = false
      myCompo.disabledNew = false
      myCompo.disabledEdit = false
      myCompo.disabledSave = true
      myCompo.disabledCancel = true
    }
  }
)

// action 변경 함수
const setAction = (newAction) => {
  myCompo.action = newAction
}
</script>

<template>
  <div>
    <h3>현재 상태: {{ myCompo.action }}</h3>
    
    <!-- 그리드 (가상 컴포넌트로 표현) -->
    <div :class="{ 'grid-disabled': myCompo.disabledGrid }" class="grid">
      데이터 그리드
    </div>

    <!-- 버튼들 -->
    <button :disabled="myCompo.disabledNew" @click="setAction('insert')">
      New
    </button>
    <button :disabled="myCompo.disabledEdit" @click="setAction('edit')">
      Edit
    </button>
    <button :disabled="myCompo.disabledSave" @click="setAction('save')">
      Save
    </button>
    <button :disabled="myCompo.disabledCancel" @click="setAction('cancel')">
      Cancel
    </button>
    <button @click="setAction('normal')">Reset to Normal</button>
  </div>
</template>

<style scoped>
.grid {
  border: 1px solid #ccc;
  padding: 10px;
  margin-bottom: 10px;
}
.grid-disabled {
  background-color: #f0f0f0;
  opacity: 0.5;
}
button {
  margin-right: 5px;
}
button:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}
</style>
코드 설명
1. reactive로 반응형 데이터 정의
  • myCompo 객체를 reactive로 선언해 모든 속성을 반응형으로 만듭니다.
  • 초기값은 action: 'normal'에 맞춰 설정했습니다.
2. watch로 상태 감시
  • watch(() => myCompo.action, ...)를 사용해 action 값의 변화를 감지합니다.
  • newAction 값에 따라 조건문으로 각 속성을 업데이트합니다.
  • else 블록을 추가해 'normal' 등 기타 상태에서도 초기값으로 복원되도록 했습니다.
3. 템플릿에서 바인딩
  • 그리드: 실제 그리드 컴포넌트 대신 <div>로 가상 구현했습니다. :classdisabledGrid 상태에 따라 스타일을 조정합니다.
  • 버튼: :disabled 디렉티브로 각 버튼에 disabled 속성을 바인딩했습니다. 예: <button :disabled="myCompo.disabledNew">.
  • 버튼 클릭 시 setAction 함수로 action 값을 변경해 테스트할 수 있습니다.
4. 스타일링
  • 그리드와 버튼의 비활성화 상태를 시각적으로 구분하기 위해 간단한 CSS를 추가했습니다.
동작 확인
  • 초기 상태: New, Edit 버튼은 활성화, Save, Cancel은 비활성화.
  • New 클릭: action'insert'로 바뀌며 그리드와 New/Edit 버튼이 비활성화되고, Save/Cancel이 활성화.
  • Save 클릭: action'save'로 바뀌며 초기 상태로 복원.
  • Reset 클릭: action'normal'로 돌아감.
장점
  • watch를 활용해 데이터와 UI 상태를 일치시킴.
  • 반응형 객체로 코드가 간결하고 유지보수 쉬움.
  • 실제 프로젝트에서 그리드 컴포넌트(예: AG-Grid)와 통합 가능.
결론
Vue.js의 반응형 시스템과 watch는 UI 상태 관리를 매우 효율적으로 만들어줍니다. 이 예제를 기반으로 실제 프로젝트에 맞게 확장해보세요!
 
728x90