Files
2nd/10_Wiki/Topics/Frontend/Computed_Properties_&_Watchers.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

5.0 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-computed-properties-watchers Computed Properties & Watchers 10_Wiki/Topics verified self
Vue computed
Vue watch
reactive-derivations
none A 0.9 applied
vue
reactivity
composition-api
computed
watch
2026-05-10 pending
language framework
typescript vue3

Computed Properties & Watchers

매 한 줄

"매 derived state 의 declarative cache (computed), 매 side-effect 의 explicit subscription (watch)". 매 Vue 3.5 (2024) reactive system 의 두 축. 매 computed 는 pull-based memoization, watch 는 push-based callback.

매 핵심

매 computed 의 본질

  • 매 dependency 의 자동 추적 → 매 read 시점 lazy evaluation.
  • 매 동일 input 의 cached return — Object.is 비교.
  • 매 ref 처럼 .value 의 unwrap.
  • 매 writable computed 의 setter 정의 가능.

매 watch / watchEffect 의 차이

  • watch(source, cb): 매 explicit source — 매 old/new value 의 access.
  • watchEffect(fn): 매 자동 dep tracking — 매 deps mutation 시 fn 의 re-run.
  • 매 flush timing: 'pre' (default, before render) / 'post' (after DOM) / 'sync' (즉시).

매 Vue 3.5 reactivity 개선

  • computed 의 lazy invalidation — 매 unused chain 의 skip.
  • 매 SSR friendly — server 에서 watch 의 no-op.
  • 매 onWatcherCleanup() 의 자동 cleanup hook.

💻 패턴

Basic computed

import { ref, computed } from 'vue';

const firstName = ref('Yuna');
const lastName = ref('Kim');
const fullName = computed(() => `${firstName.value} ${lastName.value}`);

console.log(fullName.value); // "Yuna Kim" — cached
firstName.value = 'Jihoon';
console.log(fullName.value); // 매 invalidate → recompute

Writable computed

const count = ref(0);
const double = computed({
  get: () => count.value * 2,
  set: (v) => { count.value = v / 2; },
});

double.value = 10; // count.value === 5

watch (explicit source)

import { ref, watch } from 'vue';

const userId = ref(1);
const user = ref<User | null>(null);

watch(userId, async (id, oldId, onCleanup) => {
  const ctrl = new AbortController();
  onCleanup(() => ctrl.abort()); // 매 stale request 의 cancel
  user.value = await fetchUser(id, { signal: ctrl.signal });
}, { immediate: true });

watchEffect (auto-track)

import { ref, watchEffect } from 'vue';

const query = ref('');
const results = ref<Item[]>([]);

watchEffect(async (onCleanup) => {
  const ctrl = new AbortController();
  onCleanup(() => ctrl.abort());
  results.value = await searchAPI(query.value, { signal: ctrl.signal });
});

Deep watch (object/array)

const filters = reactive({ q: '', tags: [] });

watch(filters, (next) => {
  console.log('filters changed', JSON.parse(JSON.stringify(next)));
}, { deep: true });

Multiple sources

const x = ref(0), y = ref(0);
watch([x, y], ([nx, ny], [ox, oy]) => {
  console.log(`(${ox},${oy}) → (${nx},${ny})`);
});

Flush timing — DOM 접근

const list = ref<string[]>([]);
const containerRef = ref<HTMLElement>();

watch(list, () => {
  // 매 DOM 의 update 후 scrollTop 의 read
  containerRef.value!.scrollTop = containerRef.value!.scrollHeight;
}, { flush: 'post' });

매 결정 기준

상황 Approach
매 derived value (template render) computed
매 expensive computation + cache computed
매 external side-effect (fetch, DOM) watch / watchEffect
매 conditional dep tracking watch (explicit source)
매 모든 reactive read 의 react watchEffect

기본값: 매 derive 는 computed, 매 effect 는 watch with explicit source.

🔗 Graph

🤖 LLM 활용

언제: 매 Vue 3 component 의 derived data 정의, 매 async data fetch 의 dependency 변경 추적, 매 form-validation reactive chain. 언제 X: 매 React/Solid 의 코드 (각 framework 의 hook/signal 사용), 매 single-shot computation (그냥 함수).

안티패턴

  • 매 computed side-effect: 매 getter 안에서 mutation/fetch — 매 cache invalidation 의 chaos.
  • 매 watch deep 의 남용: 매 large object deep watch — 매 expensive equality check.
  • 매 immediate + cleanup 누락: 매 첫 fetch 의 race — 매 onCleanup 의 mandatory.
  • 매 watchEffect 의 conditional dep: 매 첫 run 에서 안 읽힌 ref 의 untracked.

🧪 검증 / 중복

  • Verified (Vue 3.5 docs vuejs.org/api/reactivity-core, Evan You blog 2024).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — computed/watch 의 timing/cleanup 패턴 정리