Effector Vue Bindings
Effector-vue provides official Vue bindings for the Effector state management library, enabling reactive integration of Effector's "algebraic effects" based state logic within Vue applications. It is currently stable at version 23.1.1, with releases typically aligning with major `effector` updates to ensure compatibility and leverage new features. The library's core strength lies in offering a thin, efficient layer to connect Effector's immutable stores and events with Vue's reactivity system, primarily through the `useUnit` hook for the Composition API. This approach offers a powerful, declarative data flow paradigm, emphasizing explicit data transformations and event handling as an alternative to traditional Flux-like patterns. It supports both Vue 3 Composition API and Options API, facilitating diverse project setups and migrations from older Vue versions.
Common errors
-
SyntaxError: The requested module 'vue' does not provide an export named 'default'
cause Incorrect module resolution for Vue's ESM exports within `effector-vue`'s internal structure or the consuming project's bundler configuration.fixCheck your bundler (Webpack, Vite, Rollup) configuration to ensure proper handling of Vue 3's ESM exports. Sometimes this can be resolved by upgrading bundler versions or ensuring explicit ESM-friendly settings. -
Cannot find module 'effector' or 'vue'
cause Peer dependencies `effector` or `vue` are not installed or do not meet the specified version range.fixInstall `effector` and `vue` (and `@vue/reactivity`, `@vue/runtime-core`) using your package manager: `npm install effector vue @vue/reactivity @vue/runtime-core` or `yarn add effector vue @vue/reactivity @vue/runtime-core`. -
TypeError: Cannot read properties of undefined (reading 'value') when accessing state from useUnit
cause Attempting to access a reactive property `value` on a non-reactive or `undefined` result from `useUnit`, or not unwrapping `ref`s correctly.fixEnsure the Effector unit passed to `useUnit` is a valid store or event. Remember that `useUnit` for stores returns a `Ref` in Vue 3, so access its value with `.value` in `<script setup>` or in a `render` function if it's not automatically unwrapped. -
[Vue warn]: Failed to resolve component: <ComponentName> (or similar errors related to Gate components)
cause When using `createGate` or `useGate`, the component might not be correctly registered or its props might not align with the Gate's expectations.fixEnsure `createGate` is defined correctly. If using `useGate`, ensure it's called within a component's `setup` function. Double-check that component props passed to the Gate align with its defined type signature.
Warnings
- breaking Effector 23 deprecated several operators like `forward` and `guard` in favor of `sample`. While `effector-vue` itself might not directly use these, applications using older Effector patterns may see deprecation warnings.
- gotcha Direct mutation of Effector stores (e.g., `$store.value = newValue`) is not supported and will not trigger updates. Effector stores are immutable, and state changes must always occur through events or effects.
- gotcha `effector-vue` provides separate entry points for the Composition API (`effector-vue/composition`) and Options API (`effector-vue/options-vue3`). Incorrectly importing from the root `effector-vue` or the wrong subpath can lead to runtime errors.
- gotcha The `effector-vue/composition` module is slated for deprecation in `effector@24` and removal in `effector@25`, with hooks moving to the main `effector-vue` module.
- gotcha Some users have reported `SyntaxError: The requested module 'vue' does not provide an export named 'default'` when importing `effector-vue` in Vue 3 projects, related to how Vue is imported within the library's barrel file.
Install
-
npm install effector-vue -
yarn add effector-vue -
pnpm add effector-vue
Imports
- useUnit
import { useUnit } from 'effector-vue';import { useUnit } from 'effector-vue/composition'; - VueEffector
import { VueEffector } from 'effector-vue';import { VueEffector } from 'effector-vue/options-vue3'; - createStore
import { createStore } from 'effector-vue';import { createStore } from 'effector';
Quickstart
import {createStore, createEvent} from 'effector'
import {useUnit} from 'effector-vue/composition'
import { defineComponent, h } from 'vue';
export const inputText = createEvent<string>()
export const $text = createStore<string>('').on(inputText, (_, text) => text)
export const $size = $text.map(text => text.length)
const App = defineComponent({
setup() {
const text = useUnit($text)
const size = useUnit($size)
const handleTextChange = useUnit(inputText)
return () =>
h('form', [
h('input', {
type: 'text',
onInput: (e: Event) => handleTextChange((e.target as HTMLInputElement).value),
value: text.value
}),
h('p', `Length: ${size.value}`)
])
}
});
// To run in a browser or test environment (example setup)
if (typeof window !== 'undefined') {
import { createApp } from 'vue';
const app = createApp(App);
app.mount('#app');
}