All Projects → zetaplus006 → vue-class-state

zetaplus006 / vue-class-state

Licence: MIT license
面向对象风格的vue状态管理

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to vue-class-state

Ayanami
🍭 A better way to react with state
Stars: ✭ 129 (+821.43%)
Mutual labels:  state-management, decorators
mount-up
watching mount's ups and downs
Stars: ✭ 26 (+85.71%)
Mutual labels:  state-management
Tailor made
✄ Managing a Fashion designer's daily routine.
Stars: ✭ 219 (+1464.29%)
Mutual labels:  state-management
Vue Class Store
Universal Vue stores you write once and use anywhere
Stars: ✭ 243 (+1635.71%)
Mutual labels:  state-management
Use Machine
React Hook for using Statecharts powered by XState. use-machine.
Stars: ✭ 226 (+1514.29%)
Mutual labels:  state-management
Final Form
🏁 Framework agnostic, high performance, subscription-based form state management
Stars: ✭ 2,787 (+19807.14%)
Mutual labels:  state-management
Hydux
A light-weight type-safe Elm-like alternative for Redux ecosystem, inspired by hyperapp and Elmish
Stars: ✭ 216 (+1442.86%)
Mutual labels:  state-management
react-context
(つ°ヮ°)つ Understanding React Context
Stars: ✭ 11 (-21.43%)
Mutual labels:  state-management
generic bloc provider
Generic BloC provider implementation
Stars: ✭ 26 (+85.71%)
Mutual labels:  state-management
Model
Angular Model - Simple state management with minimalist API, one way data flow, multiple model support and immutable data exposed as RxJS Observable.
Stars: ✭ 242 (+1628.57%)
Mutual labels:  state-management
Redux Tiles
Composable way to create less verbose Redux code
Stars: ✭ 239 (+1607.14%)
Mutual labels:  state-management
Getx pattern
Design pattern designed to standardize your projects with GetX on Flutter.
Stars: ✭ 225 (+1507.14%)
Mutual labels:  state-management
Citrus
State management library for Rum
Stars: ✭ 248 (+1671.43%)
Mutual labels:  state-management
React Organism
Dead simple React state management to bring pure components alive
Stars: ✭ 219 (+1464.29%)
Mutual labels:  state-management
react-globally
Gives you setGlobalState, so you can set state globally
Stars: ✭ 22 (+57.14%)
Mutual labels:  state-management
Devonfw4flutter
A guide aiming to bridge the gap between the absolute Flutter basics and clean, structured Flutter Development
Stars: ✭ 219 (+1464.29%)
Mutual labels:  state-management
React Agent
Client and server-side state management library
Stars: ✭ 235 (+1578.57%)
Mutual labels:  state-management
Pulse
✨ Pulse is a global state and logic framework for reactive Typescript & Javascript applications. Supporting frameworks like VueJS, React and React Native.
Stars: ✭ 243 (+1635.71%)
Mutual labels:  state-management
random-users-details
Random Users details in flutter from randomusers api
Stars: ✭ 14 (+0%)
Mutual labels:  state-management
enform
Handle React forms with joy 🍿
Stars: ✭ 38 (+171.43%)
Mutual labels:  state-management

vue-class-state

Vue状态管理,灵感来自mobx

vue-class-state提供以下功能:

1.stategettersmutation,其概念与vuex基本相通,区别是vue-class-state是以class(类)和decorator(装饰器)的形式来实现的。

2.简单的依赖注入,用于解决子模块之间共享数据的问题,也可与Vue的provide/inject配合使用。

3.支持严格模式,开启后state只能在mutation中被修改,支持拦截mutation。

4.支持vue官方devtool,可以在devtool的vuex标签下查看stategettersmutation

安装

npm install vue vue-class-state --save

注意:

1.TypeScript用户需要开启tsconfig.json中的experimentalDecoratorsallowSyntheticDefaultImports的编译选项

2.javaScript+Babel用户需要babel-plugin-transform-decorators-legacybabel-plugin-transform-class-properties插件。

基本使用

// store.ts

import { bind, Container, Getter, Inject, State } from 'vue-class-state';

// 定义注入标识
export const StateKeys = {
    A: 'stateA',
    B: 'stateB',
    STORE: 'store'
};

export class StateA {
    // 定义响应式数据
    @State text = 'A';
}

export class StateB {
    @State text = 'B';
}

export class Store {

    // 根据注入标识在将实例注入到类实例属性中
    // 并且在第一次读取该属性时才进行初始化
    // @Inject(StateKeys.A)  stateA!: StateA

    constructor(
        // 根据注入标识在将实例注入到构造器参数中
        @Inject(StateKeys.A) public stateA: StateA,
        @Inject(StateKeys.B) public stateB: StateB
    ) {
    }

    // 定义计算属性,
    // 并且在第一次读取该属性时才进行该计算属性的初始化
    @Getter get text() {
        return this.stateA.text + this.stateB.text;
    }

}

// 定义容器
@Container({
    providers: [
        // 绑定注入规则,一个标识对应一个类实例(容器范围内单例注入)
        bind<StateA>(StateKeys.A).toClass(StateA),
        bind<StateB>(StateKeys.B).toClass(StateB),
        bind<Store>(StateKeys.STORE).toClass(Store)
    ],
    // 开启严格模式
    strict: true
})
export class AppContainer { }
// app.ts

import Vue from 'vue';
import Component from 'vue-class-component';
import { Inject } from 'vue-class-state';
import { AppContainer, StateKeys, Store } from './store';

// 推荐使用vue官方的vue-class-component库
@Component({
    template: '<div>{{store.text}}</div>'
})
class App extends Vue {

    // 根据注入标识在子组件中注入实例
    @Inject(StateKeys.STORE) store!: Store;

}

new Vue({
    el: '#app',
    // 在根组件实例化一个容器,传入到provide选项
    provide: new AppContainer(),
    render: (h) => h(App)
});

注册类

bind<IModule>(moduleKeys.A).toClass(ModuleA)

注册值

bind<IModule>(moduleKeys.A).toValue(new ModuleA())

注册工厂

bind<IModule>(moduleKeys.A).toFactory(() => new ModuleA())

// 传入的第二个参数类型为注入标识数组,表明该工厂依赖的其他模块,会依次注入到工厂参数中
bind<IModule>(moduleKeys.B).toFactory((moduleA: IModule, moduleB: IModule) => {
    return new ModuleC(moduleA, moduleB)
}, [moduleKeys.A, moduleKeys.B])


bind<IModule>(moduleKeys.B).toFactory((moduleA: IModule, moduleB: IModule) => {
    if (isSSR) {
        return moduleA
    } else {
        return moduleB
    }
}, [moduleKeys.A, moduleKeys.B])

拦截mutation

以下是简单的缓存例子

import Vue from 'vue';
import { bind, Container, IMutation, Mutation, State } from 'vue-class-state';

// 如果想拦截某些Mutation的执行,可以创建一个新的装饰器,执行顺序和 koa(直接抄它的)一样,洋葱模型,但不支持异步
const CacheMutation = Mutation.create((next: () => void, mutation: IMutation, state: Counter) => {
    // mutation 执行前打印相关信息
    console.log(`
        mutation类型,供devtool使用: ${mutation.type}
        传入mutation方法的参数数组: ${JSON.stringify(mutation.payload)}
        调用的模块注入标识: ${mutation.identifier}
        调用的方法名: ${mutation.mutationType}
    `);
    const res = next();
    // mutation 执行后保存缓存
    localStorage.setItem(state.cacheKey, JSON.stringify(state));
    return res;
});

class Counter {

    cacheKey = 'cache-key';

    @State public num = 0;

    // 严格模式下,修改实例的state值必须调用该实例的Mutation方法
    // 和vuex一致,必须为同步函数
    @CacheMutation
    public add() {
        this.num++;
    }

    // 默认的Mutation不会被拦截
    @Mutation
    public add2() {
        this.num++;
    }

    constructor() {
        const cacheStr = localStorage.getItem(this.cacheKey);
        if (cacheStr) {
            const cache = JSON.parse(cacheStr);
            State.replaceState(this, cache);
        }
        setInterval(() => {
            // 等同于 CacheMutation.commit(this, () => this.num++, 'add');
            // 最简化写法 CacheMutation.commit(() => this.num++) ,注意由于没有传入this,这种写法中间件是拿不到state的,看情况使用
            this.add();
        }, 1000);
    }
}

const COUNTER = 'counter';

@Container({
    providers: [bind<Counter>(COUNTER).toClass(Counter)],
    strict: [COUNTER]
})
class AppContainer { }

const container = new AppContainer();

new Vue({
    el: '#app',
    template: `<div>{{counter.num}}</div>`,
    computed: {
        counter() {
            return container[COUNTER];
        }
    }
});
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].