MobX Class & JSX helpers for Vue 3 components, providing seamless integration with MobX state management for both class and function components.
- π― Universal Support: Works with both
classandfunctioncomponents - π Auto Reactivity: Automatically tracks and reacts to MobX observable state changes
- β‘ Reaction Decorator:
@reaction()decorator for declarative side effects on observable changes - π¨ TypeScript First: Full TypeScript support with type definitions
- π Easy to Use: Simple
@observerdecorator API, similar tomobx-react - πͺ Vue 3 Compatible: Built for Vue 3 with composition API support
npm install mobx mobx-vue-helper vue-facing-decoratorimport { Vue, Component, toNative } from 'vue-facing-decorator';
import { observer } from 'mobx-vue-helper';
import counterStore from './models/Counter';
@Component
@observer
class MyMobX extends Vue {
render() {
return <button onClick={() => counterStore.increment()}>Count: {counterStore.count}</button>;
}
}
export default toNative(MyMobX);import { observer } from 'mobx-vue-helper';
import counterStore from './models/Counter';
export const MyMobX = observer(() => (
<button onClick={() => counterStore.increment()}>Count: {counterStore.count}</button>
));import { observable } from 'mobx';
export class CounterStore {
@observable
accessor count = 0;
increment() {
this.count++;
}
decrement() {
this.count--;
}
}
export default new CounterStore();The @reaction() decorator allows you to define side effects that run when specific observable values change. It's based on MobX's reaction().
import { Vue, Component, toNative } from 'vue-facing-decorator';
import { observer, reaction } from 'mobx-vue-helper';
import counterStore from './models/Counter';
@Component
@observer
class MyComponent extends Vue {
// This method will be called whenever count changes
@reaction(() => counterStore.count)
handleCountChange(newValue: number, oldValue: number) {
console.log(`Count changed from ${oldValue} to ${newValue}`);
}
render() {
return <button onClick={() => counterStore.increment()}>Count: {counterStore.count}</button>;
}
}
export default toNative(MyComponent);Note: The @reaction() decorator should be used with the @observer decorator on the class. Reactions are automatically disposed when the component is unmounted.
The @observer decorator wraps your component's render function with MobX's <Observer /> component from mobx-vue-lite. This enables automatic tracking of observable access during render and triggers re-renders when tracked observables change.
- For class components: The decorator uses class inheritance to extend your original component, wrapping the
render()method and managing MobX reactions lifecycle - For function components: The wrapper creates a Vue component with a setup function that wraps your functional component
The @reaction() decorator allows you to define MobX reactions directly on class methods. These reactions are automatically initialized when the component mounts and disposed when it unmounts.
As the implementation of Vue 3 & Vue-facing-decorator are dependent on Proxy API, and MobX 6+ & ES Decorator stage-3 are dependent on accessor properties (which is used the Private Field inside), it'll throw errors when they are working together, so we can't put @observable on fields of class components directly as React & WebCell do.
You need to create a separate store class with @observable properties and use it inside your Vue class component:
import { Vue, Component, toNative } from 'vue-facing-decorator';
import { observable } from 'mobx';
import { observer } from 'mobx-vue-helper';
class State {
@observable
accessor count = 0;
increment() {
this.count++;
}
decrement() {
this.count--;
}
}
const state = new State();
@Component
@observer
class MyMobX extends Vue {
render() {
return <button onClick={() => state.increment()}>Count: {state.count}</button>;
}
}
export default toNative(MyMobX);- TypeScript 5.x
- Vue 3.x
- MobX 6.x
- Vue-facing-decorator 4.x
This package is part of the idea2app ecosystem and is inspired by the observer pattern from mobx-react.