import { useVModel } from "effector-vue/composition";useVModel появился в effector-vue 21.1.0
Возвращает записываемый ref, связанный со стором: обновление стора доходит до ref, а правка ref записывается в стор. В основном нужен для форм с v-model во Vue 3.
Методы
useVModel($store, options?)
Формула
useVModel($store: Store<State>, options?: UseVModelOptions): Ref<UnwrapRef<State>>;useVModel<T extends Record<string, Store<any>>>(shape: T, options?: UseVModelOptions): ExtractStore<T>;Для Vue 3.
Аргументы
$store(Стор) или объект сторовoptions?(Object)scope?(Scope): скоуп для чтения и записи вместо скоупа плагинаforceScope?(boolean): бросить ошибку, если скоуп не найден, вместо перехода в глобальный режимdeep?(boolean): глубокое отслеживание значения, чтобы правка вложенного поля доходила до стора (по умолчаниюtrue)
Аргумент options появился в effector-vue 23.3.0. Раньше вторым аргументом был Vue EffectScope, и эта форма работает по-прежнему
Возвращает
Записываемый Ref с копией состояния, а для объекта сторов объект таких копий. Правка записывает в стор всё новое значение целиком, а обновление стора заменяет копию.
Примеры
Один стор
import { createStore } from "effector";
export const $user = createStore({ name: "", surname: "", skills: ["CSS", "HTML"],});<script setup lang="ts">import { useVModel } from "effector-vue/composition";
import { $user } from "./model";
const user = useVModel($user);</script>
<template> <input type="text" v-model="user.name" /> <input type="text" v-model="user.surname" />
<div> <input type="checkbox" v-model="user.skills" value="HTML" /> <input type="checkbox" v-model="user.skills" value="CSS" /> <input type="checkbox" v-model="user.skills" value="JS" /> </div></template>Объект сторов
import { createStore } from "effector";
export const $name = createStore("");export const $surname = createStore("");export const $skills = createStore<string[]>([]);<script setup lang="ts">import { useVModel } from "effector-vue/composition";
import { $name, $surname, $skills } from "./model";
const user = useVModel({ name: $name, surname: $surname, skills: $skills });</script>
<template> <input type="text" v-model="user.name" /> <input type="text" v-model="user.surname" />
<div> <input type="checkbox" v-model="user.skills" value="HTML" /> <input type="checkbox" v-model="user.skills" value="CSS" /> <input type="checkbox" v-model="user.skills" value="JS" /> </div></template>Скоуп
useVModel пишет в скоуп с effector-vue 23.3.0. Раньше правка попадала в глобальный стор даже при установленном плагине
С EffectorScopePlugin форма читает и пишет скоуп приложения, поэтому ввод пользователя попадает в scope.getState($form) и в serialize. Без скоупа пишется сам стор, как раньше.
import { fork } from "effector";import { EffectorScopePlugin } from "effector-vue/composition";
const scope = fork();app.use(EffectorScopePlugin({ scope }));Вызов вне компонента или вызов, который должен писать в другой скоуп, получает скоуп через опцию:
const form = useVModel($form, { scope });Неглубокая привязка
По умолчанию копия отслеживается глубоко, поэтому правка вложенного поля записывает в стор всё новое значение. С deep: false состояние стора привязывается как есть, и обратно пишется только присваивание всего значения. Это подходит для формы из примитивов или для большого состояния, которое в основном читают:
const form = useVModel($form, { deep: false });
form.value = { ...form.value, name: "John" };В этом режиме ref держит сам объект состояния стора, а присваивание отдаёт этот объект обратно без копии. Запись во вложенное поле меняет состояние стора на месте, и никто не считает это обновлением: стор хранит тот же объект, и ни один наблюдатель не срабатывает. Заменяйте значение целиком, как в примере, или не трогайте deep.
Ограничения
Копия делается через structuredClone с effector-vue 23.3.0
- Копия состояния делается через
structuredClone, поэтомуDate,Map,Set,RegExpи типизированные массивы переживают круг туда и обратно. Если в среде нетstructuredCloneили он бросает ошибку на каком-то значении в состоянии, например на функции, вся копия делается простым рекурсивным копированием. Такая копия держит функции и даты по ссылке, аMapиSetпревращает в пустые объекты. Экземпляр класса в обоих случаях теряет прототип. - Производный стор, результат
mapилиcombine, принимает правку, и следующее обновление исходного стора её перезаписывает. Хук сообщает об этом черезconsole.error: привязывайте форму к исходному стору. - Раньше вторым аргументом был Vue
EffectScope. Эта форма работает, но предпочтительна форма с объектом опций.
Документация на английском языке - самая актуальная, поскольку её пишет и обновляет команда effector. Перевод документации на другие языки осуществляется сообществом по мере наличия сил и желания.
Помните, что переведенные статьи могут быть неактуальными, поэтому для получения наиболее точной и актуальной информации рекомендуем использовать оригинальную англоязычную версию документации.