Этот проект демонстрирует решение проблемы приоритета атрибутов (Props vs Fallthrough Attributes) в Vue 3 с использованием patch-package.
В стандартном поведении Vue 3 атрибуты, передаваемые через $attrs ("сквозные атрибуты"), имеют приоритет над явно заданными пропсами при слиянии вложенных компонентов.
Сценарий:
Parentпередает атрибутdisabledвMiddleComponent.- Атрибут не объявлен в
propsпромежуточного компонента, поэтому попадает в$attrs. MiddleComponentявно передает:disabled="false"вChildComponent.
Ожидаемое поведение: ChildComponent получает false.
Фактическое поведение (без патча): ChildComponent получает true (значение из $attrs перезаписывает явный проп).
<!-- App.vue -->
<Comp1 disabled /> <!-- Передаем true -->
<!-- Comp1.vue -->
<Comp2 :disabled="false" /> <!-- Пытаемся передать false, но Vue игнорирует это -->В проект внедрен патч для пакета @vue/runtime-core. Он изменяет логику функции mergeProps, меняя стратегию слияния с "последний побеждает" на "первый побеждает" для атрибутов.
Если атрибут уже был задан явно (существует в результирующем объекте), значение из $attrs игнорируется.
Файл патча: /patches/@vue+runtime-core+3.x.x.patch
-
Установка зависимостей:
npm install
После установки автоматически запустится скрипт
postinstall, который применит патч кnode_modules. -
Запуск проекта:
npm run dev
- Откройте приложение в браузере.
- Найдите тестовый компонент (кнопку или инпут), который принимает
disabled. - Результат: Кнопка должна быть активна (не заблокирована), несмотря на то, что родитель передал атрибут блокировки. Это подтверждает, что явный проп
:disabled="false"победил.
Патчи привязаны к конкретной версии пакета. Если вы обновите версию Vue (например, через npm update или npm install vue@latest), patch-package выдаст предупреждение, и патч может не примениться.
Алгоритм действий при обновлении библиотеки:
-
Удалите старый патч: Удалите файл
.patchиз папкиpatches/, относящийся к@vue/runtime-core. -
Внесите изменения вручную: Откройте файл:
node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.jsНайдите функцию
function mergeProps(...args).Найдите блок:
} else if (key !== "") { ret[key] = toMerge[key]; // Statement expected }
Замените его на:
} else if (key !== "") { // Patch: Приоритет явных пропсов. Не перезаписывать, если ключ уже есть. if (ret[key] === undefined) { ret[key] = toMerge[key]; } }
-
Сгенерируйте новый патч: Выполните команду в терминале:
npx patch-package @vue/runtime-core
-
Зафиксируйте изменения: В папке
patches/появится новый файл с актуальной версией. Закоммитьте его в git.