3. Поиск с подсказками: debounce, отмена запроса, состояния loading/error/empty.
Что оценивают
Debounce ввода, AbortController (гонки), обработку ошибок, key в списке, доступность (role="listbox", стрелки, Enter), очистку при размонтировании.
4. Бесконечный список: подгрузка при прокрутке.
Решение
Sentinel-элемент + useIntersectionObserver; защита от повторных запросов (loading, hasMore); сохранение позиции прокрутки; отмена при размонтировании.
5. Вкладки (Tabs/Tab) через provide/inject или component :is, клавиатурная навигация.
6. Модальное окно: Teleport, focus trap, закрытие по Esc и клику вне, блокировка прокрутки, aria-modal.
7. Реализуйте useLocalStorage(key, default) с синхронизацией между вкладками.
Решение
export function useLocalStorage\<T>(key: string, def: T) { const read = () => { try { const v = localStorage.getItem(key); return v ? (JSON.parse(v) as T) : def; } catch { return def; } }; const state = ref(read()) as Ref\<T>; watch(state, (v) => localStorage.setItem(key, JSON.stringify(v)), { deep: true }); useEventListener(window, "storage", (e: StorageEvent) => { if (e.key === key) state.value = read(); }); return state;}
8. Найдите ошибки в коде.
<script setup>const { user } = useUser(); // user — не реактивен, если composable вернул reactiveconst list = reactive([]);async function load() { list = await api.list(); } // замена reactive</script><template><li v-for="(x, i) in list" :key="i" v-if="x.active">{{ x.name }}</li></template>
Ответ
Потеря реактивности при деструктуризации и присваивании list, v-if вместе с v-for, ключ по индексу; исправление — ref/toRefs, computed для фильтрации, key = x.id.
Как вести себя на live coding
Уточните требования (props, события, доступность, состояния).
Набросайте интерфейс компонента (props/emits/slots), затем реализацию.