$bindable в Svelte: Упрощение работы с двухсторонними привязками
-
$bindable
— это специальная директива в Svelte 5+, которая позволяет помечать переменные как двухсторонне связуемые (bindable) в рамках компонента. Это означает, что вы можете использовать bind: на кастомных компонентах так же, как вы используете его, например, на нативном элементе<input bind:value>
Ранее для этого требовалось писать отдельный механизм обработки событий (dispatch) и передачи значений обратно, но теперь всё это можно сделать с минимальным кодом благодаря $bindable.
Как работает $bindable
Когда вы пишете:
let count = $bindable(0);
Вы создаёте реактивное свойство, которое:
- Реактивно обновляется при изменении локально.
- Автоматически генерирует событие change при изменении значения.
- Позволяет использовать bind: в родительском компоненте без дополнительного кода.
Под капотом
$bindable
оборачивает значение в реактивную ссылку и подписывается на изменения, чтобы оповещать внешний мир через dispatch(‘change’, …). Таким образом, вы получаете прозрачный механизм двусторонней связи между компонентами.Сравнение с другими фреймворками
В современных фреймворках для работы с состоянием между компонентами используются разные подходы. В Svelte 5+ появился инструмент
$bindable
, который упрощает создание двусторонних привязок. В Vue для этого традиционно используютv-model
и события, а в React — пропсы и колбэк-функции. Рассмотрим, как эти механизмы работают, их сходства и различия.Двухсторонняя привязка: $bindable (Svelte), v-model (Vue), props + callbacks (React)
Svelte: $bindable
<!-- Counter.svelte --> <script> let count = $bindable(0); </script> <button on:click={() => count += 1}>Увеличить</button>
<!-- Родительский компонент --> <Counter bind:count={myCount} />
$bindable
автоматически генерирует событие change при изменении значения.- Родитель может использовать bind:propName для синхронизации.
Vue: v-model и события
<!-- Counter.vue --> <template> <button @click="increment">Увеличить</button> </template> <script setup> import { ref } from 'vue'; const props = defineProps(['modelValue']); const emit = defineEmits(['update:modelValue']); function increment() { emit('update:modelValue', props.modelValue + 1); } </script>
<!-- Родительский компонент --> <Counter v-model="count" />
- v-model использует modelValue как пропс и update:modelValue как событие.
- Требуется явно определять пропсы и эмитить события.
React: Пропсы и колбэк-функции
// Counter.jsx function Counter({ count, onCountChange }) { return ( <button onClick={() => onCountChange(count + 1)}> Увеличить </button> ); }
// Родительский компонент const [count, setCount] = useState(0); <Counter count={count} onCountChange={setCount} />
- React не имеет встроенной двусторонней привязки.
- Состояние обновляется через передачу функции onCountChange.
Реактивность и удобство
Svelte: Реактивность по умолчанию
- $bindable использует реактивную систему Svelte, где изменения переменной автоматически обновляют интерфейс.
- Минимум кода: let count = $bindable(0);
Vue: Явная реактивность
- Реактивность через ref, reactive, watch.
- Для v-model требуется передавать modelValue и эмитить события вручную.
React: Управление состоянием вручную
- Реактивность достигается через useState и useEffect.
- Для синхронизации нужно передавать состояние и функцию его обновления.
Фреймворк Метод Описание Svelte $bindable
Автоматически генерирует событие change
при изменении значения. Реактивность встроена
- Минимальный код
- Автоматическая реактивность
- Доступен только в Svelte 5+
- Ограниченная поддержка сложных типов (объекты, массивы)Vue v-model
+ событияИспользует props
иemit
для синхронизации. Требуется явное определение.
- Ясный API черезv-model
- Хорошо документирован
- Требуется вручную управлять событиями и пропсами
- Более многословный кодReact Пропсы и колбэки Полностью ручная реализация. Состояние обновляется через вызов функций.
- Полный контроль над состоянием
- Подходит для сложных приложений
- Нет встроенной двусторонней привязки
- Требует больше кода для простых задач -
$bindable
— это специальная директива в Svelte 5+, которая позволяет помечать переменные как двухсторонне связуемые (bindable) в рамках компонента. Это означает, что вы можете использовать bind: на кастомных компонентах так же, как вы используете его, например, на нативном элементе<input bind:value>
Ранее для этого требовалось писать отдельный механизм обработки событий (dispatch) и передачи значений обратно, но теперь всё это можно сделать с минимальным кодом благодаря $bindable.
Как работает $bindable
Когда вы пишете:
let count = $bindable(0);
Вы создаёте реактивное свойство, которое:
- Реактивно обновляется при изменении локально.
- Автоматически генерирует событие change при изменении значения.
- Позволяет использовать bind: в родительском компоненте без дополнительного кода.
Под капотом
$bindable
оборачивает значение в реактивную ссылку и подписывается на изменения, чтобы оповещать внешний мир через dispatch(‘change’, …). Таким образом, вы получаете прозрачный механизм двусторонней связи между компонентами.Сравнение с другими фреймворками
В современных фреймворках для работы с состоянием между компонентами используются разные подходы. В Svelte 5+ появился инструмент
$bindable
, который упрощает создание двусторонних привязок. В Vue для этого традиционно используютv-model
и события, а в React — пропсы и колбэк-функции. Рассмотрим, как эти механизмы работают, их сходства и различия.Двухсторонняя привязка: $bindable (Svelte), v-model (Vue), props + callbacks (React)
Svelte: $bindable
<!-- Counter.svelte --> <script> let count = $bindable(0); </script> <button on:click={() => count += 1}>Увеличить</button>
<!-- Родительский компонент --> <Counter bind:count={myCount} />
$bindable
автоматически генерирует событие change при изменении значения.- Родитель может использовать bind:propName для синхронизации.
Vue: v-model и события
<!-- Counter.vue --> <template> <button @click="increment">Увеличить</button> </template> <script setup> import { ref } from 'vue'; const props = defineProps(['modelValue']); const emit = defineEmits(['update:modelValue']); function increment() { emit('update:modelValue', props.modelValue + 1); } </script>
<!-- Родительский компонент --> <Counter v-model="count" />
- v-model использует modelValue как пропс и update:modelValue как событие.
- Требуется явно определять пропсы и эмитить события.
React: Пропсы и колбэк-функции
// Counter.jsx function Counter({ count, onCountChange }) { return ( <button onClick={() => onCountChange(count + 1)}> Увеличить </button> ); }
// Родительский компонент const [count, setCount] = useState(0); <Counter count={count} onCountChange={setCount} />
- React не имеет встроенной двусторонней привязки.
- Состояние обновляется через передачу функции onCountChange.
Реактивность и удобство
Svelte: Реактивность по умолчанию
- $bindable использует реактивную систему Svelte, где изменения переменной автоматически обновляют интерфейс.
- Минимум кода: let count = $bindable(0);
Vue: Явная реактивность
- Реактивность через ref, reactive, watch.
- Для v-model требуется передавать modelValue и эмитить события вручную.
React: Управление состоянием вручную
- Реактивность достигается через useState и useEffect.
- Для синхронизации нужно передавать состояние и функцию его обновления.
Фреймворк Метод Описание Svelte $bindable
Автоматически генерирует событие change
при изменении значения. Реактивность встроена
- Минимальный код
- Автоматическая реактивность
- Доступен только в Svelte 5+
- Ограниченная поддержка сложных типов (объекты, массивы)Vue v-model
+ событияИспользует props
иemit
для синхронизации. Требуется явное определение.
- Ясный API черезv-model
- Хорошо документирован
- Требуется вручную управлять событиями и пропсами
- Более многословный кодReact Пропсы и колбэки Полностью ручная реализация. Состояние обновляется через вызов функций.
- Полный контроль над состоянием
- Подходит для сложных приложений
- Нет встроенной двусторонней привязки
- Требует больше кода для простых задач -