Code Monkey home page Code Monkey logo

vuex-class-modules's People

Contributors

alsotang avatar bodograumann avatar budziam avatar dependabot[bot] avatar frankshaka avatar ftes avatar gertqin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

vuex-class-modules's Issues

jest typescript fails

after deciding to use vuex-class-modules this happened :

● Test suite failed to run

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html

Details:

/Users/vandries/workspaces/rba.ui/node_modules/vuex-class-modules/lib/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export { Action } from "./actions";
                                                                                         ^^^^^^

SyntaxError: Unexpected token 'export'

  2 | // import ... // removed
  3 | // import ...// removed
> 4 | import { VuexModule, Module, Mutation, Action } from 'vuex-class-modules';
    | ^
  5 | import store from '../index';
  6 | 
  7 | @Module

  at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
  at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)

the app works as expected
vue,typescript,vuex (default generated by vue cli)

Create independent modules

I really like the way this feature looks. Unfortunately I can not use it as-is.

Afaics with vuex-class-modules you always have to import the applications main vuex store object. When the application is composed from multiple packages and the store assembled with store.registerModule, this is not possible.

Do you think there is a way to define the vuex module independently of the main store and register it later?

module inheritance

is it possible to use inheritance to reuse common logic between modules using this package?

Allow access to setter mutations

When using the generateMutationSetters option, for each state property a mutation is generated, that sets the property.

Those setter mutations are only available inside of actions, not when using the module instance directly.

Do you think we should allow access from the outside? Or would you say that it is a much better practice to only do changes in the actions?

Nuxt problem

I'm getting this error in nuxt
[nuxt] store/index.ts should export a method that returns a vuex instance.
How can i fix it?

Access generated mutations (generateMutationSetters: true) from module instance

Is there a way to use auto-generated mutations (with generateMutationSetters: true option) from the module instance? In Vue component for example?

const userModule = new UserModule({ store, name: "user" });

userModule.firstName = value;

// OR

userModule.set__firstName(value)

Or they have to be explicitly defined in this case?

Error when using hmr with vite

Error: [vuex-class-module]: A module with name 'appModule' already exists.
    at VuexClassModuleFactory3.registerVuexModule (module-factory.js:137)
    at new accessor (module.js:28)
    at appModule.ts:66

When doing a hot-reload,the above gets logged and the hot-reload is aborted.

Im exporting the module like this: export const appModule = new AppModule({ store, name: 'appModule' })

Any idea how i can"supress" this error and make it replace the module correctly?

Getters with params

How can i use getters with some params?

For example, get getUserById(id: string), but TS says A 'get' accessor cannot have parameters

Simplify throttled vuex actions

Hi,
I would like to throttle some Vuex actions, that shouldn't be performed more than once per 3 minutes. I am using lodash's throttle function like this:

@Module
class AccountsModule extends VuexModule {
  private accounts = new Array<Account>()

  @Mutation
  private setAccounts(accounts: Array<Account>) {
    this.accounts = accounts
  }

  @Action
  public async fetchAccounts() {
    this.fetchThrottled()
  }
  
  fetchThrottled = _.throttle(performFetchAccounts, 3 * 60 * 1000, { trailing: false })

  performFetchAccounts() {
    AccountsAPI.getAccounts().then(accounts => this.setAccounts(accounts))
  }
}

Is there any way to simplify this call chain, so don't have to define 3 different functions for one throttled action or vuex-class-modules' internals forbids other way?

@Module decorator does not preserve metadata

After digging into issue #6 a little more, I found the following problem. I have created a simple example in https://github.com/bodograumann/vuex-inject-modules-example.

When defining a class through:

import { decorate, inject, injectable } from "inversify";
import { RegisterOptions, Module, VuexModule } from "vuex-class-modules";

decorate(injectable(), VuexModule);

@injectable()
export default class VuexExampleModule extends VuexModule {
  constructor(@inject("VuexModuleOptions") options: RegisterOptions) {
    super(options);
  }

  get testString() {
    return "foo bar";
  }
}

inversify adds metadata to the class. In particular, calling

Reflect.getMetadata("inversify:tagged", VuexExampleModule);

gives

{ 0: [{ key: "inject", value: "VuexModuleOptions" }] }

Unfortunately, when now applying the @Module decorator as well, the metadata is not there anymore:

[]
@Module
@injectable()
export default class VuexExampleModule extends VuexModule {
  constructor(@inject("VuexModuleOptions") options: RegisterOptions) {
[]

Now the above reflection call returns undefined.

Have options independent of module

Currently the options: RegisterOptions need to contain a name. So if I want to use dependency injection, I will have to inject a different value into each module class.

For my usage of vuex-class-modules, where I only use the proxy objects directly, the name parameter is not important, apart from having to generate a unique vuex module. The best solution would of course be to just have Symbol() as the module namespace, but that is completely incompatible with vuex I think.

So my suggestion would be to either

  • allow the name option to be left out. Then, if it is not provided, generate a unique random name.
  • Or allow name to be a function, which is called to generate the name. Then the user can decide for themself whether to use a random or deterministic name.

Another thought is to somehow use the class name when generating the vuex module name.

a question about `new constructor.prototype.constructor`

import { VuexClassModuleFactory, ModuleOptions, IVuexModule } from "./module-factory";
import { VuexModule } from "./VuexModule";

type VuexModuleClass = new (...args: any[]) => VuexModule;
export function Module<T extends VuexModuleClass>(target: T): T;
export function Module(options?: ModuleOptions): ClassDecorator;
export function Module<T extends VuexModuleClass>(arg?: ModuleOptions | T): ClassDecorator | T {
  if (typeof arg === "function") {
    return moduleDecoratorFactory()(arg) as T;
  } else {
    return moduleDecoratorFactory(arg);
  }
}

function moduleDecoratorFactory(moduleOptions?: ModuleOptions) {
  return <TFunction extends Function>(constructor: TFunction): TFunction => {
    const accessor: any = function(...args: any[]) {
      const instance = new constructor.prototype.constructor(...args) as IVuexModule;
      Object.setPrototypeOf(instance, accessor.prototype);

      const factory = new VuexClassModuleFactory(constructor, instance, moduleOptions || {});

      factory.registerVuexModule();
      return factory.buildAccessor();
    };
    accessor.prototype = Object.create(constructor.prototype);
    accessor.prototype.constructor = accessor;
    return accessor;
  };
}

what is the reason for using new constructor.prototype.constructor to create instance but not new constructor?
i am a beginner, a little confused.

Vuex 4 (Vue 3) support

Hi, first of all, thank you for the amazing job you have done with this library, it is saving the day in my frontend team in so many projects.

I know that this question could sounds hasty but, do you have any plan to support Vuex 4 and Vue 3 on the next releases?
Maybe I'm confused, but I didn't found any roadmap on this project.

Cannot read property 'state' of undefined

This is not a bug, but a small problem I encountered myself, but I will encounter the cause of this problem, I think it may be due to

// register module (could be in any file)

This sentence is ambiguous, so please change it to

//suggest to write it in the store.js file'

When I write this code in the AppModule.ts file, I will be prompted Cannot read property 'state' of undefined

AppModule.ts file content

import {VuexModule, Module} from "vuex-class-modules"

@Module({generateMutationSetters: true})
export default class AppModule extends VuexModule {
  name:string = ''
}

// register module (could be in any file)
import store from "./index"
export const appModule = new AppModule({store, name: 'app'})

And when I write this code into '@plugins/store/index', everything works fine

import Vue from 'vue'
import Vuex from 'vuex'
import AppModule from "@/plugins/store/AppModule"
import TalkModule from "@/plugins/store/TalkModule"
import UserModule from "@/plugins/store/UserModule"

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {}
})

export const appModule = new AppModule({store, name: 'app'})
export const talkModule = new TalkModule({store, name: 'talk'})
export const userModule = new UserModule({store, name: 'user'})

export default store

I think the reason for this problem may be that you must instantiate the appModule before using it. If you write this paragraph in AppModule.ts, it will not be called, so you cannot instantiate the appModule object

How to passing multiple arguments to @action

Hi,

I'm completely stuck on an issue I encounter with passing multiple arguments through an action. I've tried my best to find a solution but my vuex/decorators experience is limited. Help is appreciated.

===My .ts file belonging to the vue component ===
function receives a (dynamic)number when clicking in a table and recieves a (dynamic) year when clicking.

 @raceResultsModule.Action
  loadRaceResults!: (year: any, round: any) => void;
getResults(round: number) {
    this.loadRaceResults(this.year, round);
  }

===My module .ts file with the action/axios call receives the passed dynamic values year and round===

@Action
 async loadRaceResults(data: { year: number; round: number }) {
   await axios
     .get(`http://localhost:8000/api/f1/${year}/${round}/results.json`)
     .then((response) => {
       this.raceResults = response.data.MRData.RaceTable.Races;
     })
     .catch((error) => console.log(error));
 }

If I console.log data I receive only one value(year) instead of two dynamic values(year + round). How can I accomplish this properly?

Allow usage in node app without babel

Observation

The sources are transpiled with a tsc module target of es2015.

Problem

This makes them unusable in a node app with only a typescript setup (no webpack or babel):

./node_modules/vuex-class-modules/lib/index.js:1
export { Action } from "./actions";
^^^^^^

SyntaxError: Unexpected token 'export'

Proposed solution

#46 Transpile to commonjs modules in addition to es2015.

Does it work with typescript module libs like vuex-class-modules?

the modules are dynamically loaded, nothing is being saved.

import { VuexModule, Module, Mutation, Action } from 'vuex-class-modules';
import store from '@/store';
@Module
export default class QuoteModule extends VuexModule {
}
export const quoteModule = new QuoteModule({ store, name: 'quote' });

const vuexLocal = new VuexPersistence({
  storage: window.localStorage,
  modules: ['quote'],
});

export default new Vuex.Store({
  strict: true,
  /*
  Ideally if all your modules are dynamic
  then your store is registered initially
  as a completely empty object
  */
  plugins: [vuexLocal.plugin],
});

bug with module inheritance

Trying to use this module for share common logic
Found question #13 and it works, but with bug of initializing actions (and maybe mutations too)

export default class Collection extends VuexModule {
    url = "/collection";
    items = [];

    @Action async getList() {
        //...
    }
}

@Module
export default class Projects extends Collection {
    url = "/project";
    @Action async getList() {
        // change something
    }
}

@Module
export default class Roads extends Collection {
    url = "/road";
    @Action async getList() {
        // change something else
    }
}

// init modules
import Projects from "./Projects";
export const projects = new Projects({ store, name: "projects" });
import Roads from "./Roads";
export const roads = new Roads({ store, name: "roads" });

And when I call projects/getList it calls method from roads.

I think problem is here:

if (!vuexModule.__actions) {

Child classes inherit this vuexModule.__actions property, that's why Roads' methods overwrite Projects' one.

fully support registerModule usage

This is a feature request.

Currently, I'm using vuex-module-decorators and looking for an alternative that supports dynamically managing multiple instances of same module definition. This is inherently impossible with vuex-module-decorators which requires module name to be specified with the @Module decorator in order to create accessor objects. Now that I found vuex-class-modules can do that (nice!), I found a couple of crucial registerModule features are not exposed by vuex-class-modules and wanted to leave a feedback.

From vuex docs:

registerModule(path: string | Array, module: Module, options?: Object)
Register a dynamic module.
options can have preserveState: true that allows to preserve the previous state. Useful with Server Side Rendering.

https://vuex.vuejs.org/api/#registermodule
https://vuex.vuejs.org/guide/modules.html#dynamic-module-registration

Here, following features are missing from the VuexClassModuleFactory of vuex-class-modules:

  • ability to pass Array<string> as the module path to register nested modules
  • ability to pass {preserveState: true} as an option

I'm especially looking for the latter because we use vuex-persist plugin and need to specify preserveState for each module that are previously persisted.

Thanks!

Accessing Vue instance (_vm)

Trying to access vm:

this._vm.$socket.client.emit('SomeEvent', data);

Get error:

Property '_vm' does not exist on type 'MyModule'.ts(2339)

Any idea?

$watch not working with state changes

This minimum example does not work as expected:

import Vue from 'vue'
import Vuex from 'vuex'
import { VuexModule, Module, Mutation } from 'vuex-class-modules'

Vue.use(Vuex)

@Module
class Foo extends VuexModule {
    value: string = 'abc'
    @Mutation setValue(value: string) { this.value = value }
}

const store = new Vuex.Store({})
const foo = new Foo({ store, name: 'foo' })

foo.$watch(
    f => f.value,
    (value) => { console.log(value) }  /// watch state changes and output the new value
)

foo.setBar('xyz')

Expected behavior:

Output with xyz.

Actual behavior:

Output with undefined.

I reviewed the code and found the cause may be that $watch does not get namespaced state.

In module-factory.ts:

    accessorModule.$watch = (
      fn: (arg: VuexModule) => any,
      callback: (newValue: any, oldValue: any) => void,
      options?: WatchOptions
    ) => {
      store.watch(
        (state: any, getters: any) => fn(this.buildThisProxy({ state, getters, useNamespaceKey: true })),
        callback,
        options
      );
    };

When calling this.buildThisProxy(), it should pass in state: state[name] instead.

Should I open a pull request for this?

Support for multi argument mutation

I was wondering if it is possible to improve support for multi argument mutations.

At the moment this seems to be the only way of allowing multiple arguments:

@Mutation
public mutate(payload: { a: string; b: string }): void {
  this.a = payload.a
  this.b = payload.b
}

If possible, this would be better:

@Mutation
public mutate(a: string, b: string): void {
  this.a = a
  this.b = b
}

Memoization technique with vuex-class-modules

Hi,
thanks for this awsome library. I would like to use it with memoizee to get some TTL caching. I am trying to use it this way:

import memoize from "memoizee"
import { VuexModule, Module, Mutation, Action } from "vuex-class-modules"
import { Backend } from "@/store/modules/backends/models"
import { BackendsAPI } from "./api"
import store from "@/store"

@Module
class BackendsModule extends VuexModule {
  private _backends: Array<Backend> = []

  private _getBackendsMemoized = memoize(BackendsAPI.getBackends)

  public get backends() {
    return this._backends
  }

  @Mutation
  private setBackends(backends: Array<Backend>) {
    this._backends = backends
  }

  @Action
  public async fetchBackends() {
    const backends = await this._getBackendsMemoized()
    this.setBackends(backends)
  }
}

However, I get an error saying: TypeError: this._getBackendsMemoized is not a function. Any ideas how can I use memoization in a smart way with vuex-class-modules?

Add vuex .watch API

As documented at https://vuex.vuejs.org/api/#watch, vuex allows to watch the state without having a vue component. E.g.

store.watch(
    function(state, getters) {
        return getters.loggedIn;
    },
    loggedIn => {
        …
    }
);

would execute a function every time the login state changes.

Afaics this is currently not possible when using vuex-class-modules. It would be nice to have a watch method where the callback is not called with state and getters, but with the vuex module. Maybe it should be called $watch to prevent naming conflicts.

(Note: The second parameter getters is not given with the latest vuex release v3.0.1. You’ll need the master branch for that.)

[Feature Request] Vuex Child Modules Functionality (Submodules)

Is there any kind of provision to have sub modules inside of a module?

Like in the original Vuex we have

const ModuleA {
    state: {...},
    mutations: {...},
    actions: {...},
    modules: {
        subA: ModuleSubA
    }
}

In vuex-class-modules, maybe something like this

class ModuleA {
    subA = createSubModule(ModuleSubA);
}

Please, specify if something like that already exists, or any workaround would also work

Testing Vuex actions returns undefined

Hey there,

I couldn't find anything on SO so I'd like to ask here about. I recently moved from plain JS to TS and therefore started using vuex-class-modules. However, all of my tests using VueX that were working previously just stopped working with vuex-class-modules.

Is there anything special to take care about using vuex-class-modules?

I'm running tests on Jest.


After some more digging into vuex-class-modules I have to extend my question.

Using plain Vuex actions get triggered in my test and do what they are supposed to do. However, when I set up my test with vuex-class-module, by defining a VuexModule and putting in everything I need, my test still breaks. Is there by any chance some kind of 'how to' for working with vuex-class-module?

Action method type

You define the type of an action method as TypedPropertyDescriptor<(arg?: any) => Promise<void>>'.
I think there should be more options.

  1. I want to be able to asynchronously return some value. So it should be Promise<any>.
  2. Is there a reason, that the method has to return a Promise, i.e. be asynchronous?

Request for new feature - @Onload method decorator

I was looking to create a decorator to automatically call module methods on mounting a module, so I forked the repo here and added some lines to src/module-factory and src/index.ts. I also added src/onload.ts, which is basically an adaptation of src/actions.ts.

My changes basically add support for an @Onload method decorator and has worked in my tests. I was hoping that someone could review this as I believe it adds an interesting feature.

Thanks.

wrapped Action (accessing context)

Is it possible to define an Action that gets wrapped in another function?

Example of wrapping an action using vuexfire:

actions: {
    bindTodos: firestoreAction(({ bindFirestoreRef }) => {
      // return the promise returned by `bindFirestoreRef`
      return bindFirestoreRef('todos', db.collection('todos'))
    }),
  }

I've tried a few different ways.

@Action
bindTodos1 = firestoreAction(({ bindFirestoreRef }) => {
  // return the promise returned by `bindFirestoreRef`
  return bindFirestoreRef('todos', db.collection('todos'))
})
// ^ Unable to resolve signature of property decorator when called as an expression. ts(1240)

@Action 
bindTodos2 () {
  return firestoreAction(({ bindFirestoreRef }) => {
    return bindFirestoreRef('todos', db.collection('todos'))
  })
}
// ^ compiles, and seems to execute, but does not update 'todos' state property 

bindTodos3 = firestoreAction(({ bindFirestoreRef }) => {
  return bindFirestoreRef('todos', db.collection('todos'))
})

@Action 
bindTodos4 () {
  return this.bindTodos3()
}

Is there a specific syntax or even a workaround to get a firestoreAction into a VuexModule ?

vue-router lazy loading broken

I'm having trouble using both vuex-class-modules and vue-router lazy loading at the same time.

For reference- here is a commit of the project showing the issue-
https://github.com/danieleades/lazy-load-issue

  • I have a page called 'transactions' which is lazily loaded in router.ts
    {
      path: '/transactions',
      name: 'transactions',
      component: () => import(/* webpackChunkName: "transactions" */ './views/Transactions.vue'),
    },
  • This route depends on a vuex module which is instantiated and registered in @/store/transactions.ts
const transactionsModule = new TransactionsModule({ store, name: 'transactions' });

export { transactionsModule };
import { Component, Vue } from 'vue-property-decorator';
import { transactionsModule } from '@/store/transactions';

@Component
export default class TransactionsTable extends Vue {
get transactions() {
    return transactionsModule.transactions;
}
}
  • localhost:XXXX/transactions never loads
  • page loads normally if remove the dependency on the module, or remove the lazy loading from the router.

any ideas? This library is amazing, please don't make me go back to static, stringly-typed modules!

Looks great

Hi this project looks great, just wondered if before building this you saw this project https://championswimmer.in/vuex-module-decorators/ ?

If you did, may I ask how does your project differ/ what are the benefits? Just trying to understand the differences before I select one to go with.

Thanks again

Vue Devtools not working

I recently switched to class based Vuex modules with this package.
However, the Vuex tab of Vue Devtools doesn't seem to work anymore. It just shows the base state and no modules or mutations are recorded.

Is this a known issue or just my project?

Knipsel

Using class modules with inversifyjs

I'm having problems using the vuex class modules with InversifyJS.

From the inversify docs I took

import { decorate, injectable } from "inversify";
decorate(injectable(), VuexModule);`

I’m not quite sure which order of the decorators is better, but @Module first seems sensible. I have implemented the feature #5 and added a test using InversifyJS in bodograumann/vuex-class-modules#inversify.

import { Module, VuexModule, RegisterOptions } from "../src";
import Vuex from "vuex";
import Vue from "vue";
import { Container, decorate, injectable, inject } from "inversify";
import "reflect-metadata";

Vue.use(Vuex);
const store = new Vuex.Store<any>({});

decorate(injectable(), VuexModule);

@injectable()
@Module
class MyModule extends VuexModule {
  constructor(
    @inject("Options") options: (className: string) => RegisterOptions
  ) {
    super(options);
  }

  foo = {
    text: "some text"
  };
  bar = 1;
}

const container = new Container();
container
  .bind<(className: string) => RegisterOptions>("Options")
  .toConstantValue((className: string) => ({ store, name: "myModule" }));

const myModule = container.resolve(MyModule);

test("instance of", () => {
  expect(myModule instanceof MyModule).toBe(true);
  expect(myModule instanceof VuexModule).toBe(true);
});

It fails with:

The number of constructor arguments in the derived class accessor must be >= than the number of constructor arguments of its base class.

Is it possible that @Module is not retaining the @inject annotation? In that case I thought applying @Module after @injectable() would help, or at least git a different error, but nothing changes.

Allow composition of Action, Mutation and Getter

Hi,

It would be interesting to allow the composition of each part of a module: State, Getters, Mutations, and Actions as different composed class like this example below.

class UserState {
  firstName = "Foo";
  lastName = "Bar";
  myFookingMap = new Map<String, NodeModel>();

  constructor() {
    this.myFookingMap.set("a", new NodeModel("a", "yehhhh"));
    this.myFookingMap.set("b", new NodeModel("b", "cachouu"));
  }
}

class UserMutation {
  constructor(private userState: UserState) {}

  @Mutation
  setFirstName(firstName: string) {
    this.userState.firstName = firstName;
  }

  @Mutation
  setLastName(lastName: string) {
    this.userState.lastName = lastName;
  }

  @Mutation
  setMap() {
    this.userState.myFookingMap.set("c", new NodeModel("c", "fiou"))
    this.userState.myFookingMap.get("a")!.name = "superr"
  }
}

class UserAction {
  constructor(private userState: UserState, private mutation: UserMutation) {}

  @Action
  async loadUser() {
    this.mutation.setFirstName("yao");
    this.mutation.setLastName("yeh");
  }
}

@Module
export class UserModule extends VuexModule {
  state = new UserState();
  mutation = new UserMutation(this.state);
  actions = new UserAction(this.state, this.mutation);

  // getters
  get fullName() {
    return this.state.firstName + " " + this.state.lastName;
  }
}

Do you think you can implement such a feature??

It would allow doing abstraction on each different part of a store, and thus for example make UserMutation extends from an interface or a class, and the same for UserAction etc...

Futhermore it would allow sharing parts (action, mutation, state, getters) in different modules, as below:

export const projectResourceStore = new Module({
  namespaced: true,
  state: ResourceState,
  getters: ResourceGetter,
  mutations: ResourceMutation,
  actions: ProjectResourceAction,
});

export const homeResourceStore = new Module({
  namespaced: true,
  state: ResourceState,
  getters: ResourceGetter,
  mutations: ResourceMutation,
  actions: HomeResourceAction,
}); 

Thanks!
Hope you can do something @gertqin ! (what do you think in therm of complexity to implement such a feature?)

[Question] Module Watching other module value, and initial state setting

Apologies for asking questions here.. and hoping for just pointers to point me in the right direction. If there is a better place to ask this, I'm more than happy to do that.

  1. Just guidelines around loading initial state. Most of the default state assignments work, but one needs to come from a service. Would I just create an action and somehow trigger that on start someplace to load a value from a service, and then set a state property on my store?

  2. I've got a module that handles behavior for a drop down context selector. This module is not aware of other modules. I've got a second module that basically wants to update parts of ITS state based on value set in the dropdown selector.

Pseudo code looks like this
Module1 -> SelectedContext

then

Module2 -> (when selected context changes) -> load data from a service, and set state value

I've tried lots of things for this one, and the thing that seems the closest to working, but doesnt actually work was

Create a watcher in the constructor of module2 that watches values for the SelectedContext. Then when it changes, fetch data and set value. I can see it executing every part of the code like I'd expect, but I don't see the UI reflecting the value that gets set when the context changes.

Persist state of vuex store

Hello!

I'm using your library inside an electron app built with Vue. I need to persist the state of the vuex store. To achieve this i tried saving the vuex state to a json file, using a vuex plugin. However, when i restore the state, on app launch, i get an error saying Error: [vuex-class-module]: A module with name 'myModule' already exists..

I'm pretty sure the Error originates from here:

throw Error(`[vuex-class-module]: A module with name '${name}' already exists.`);

I'm mainly wondering what the best way to solve this problem is. I was looking through the vuex docs and found a flag for registerModule called preserveState, do you think it would solve the problem if it was passed at registration time?

Question: how to persist state?

Hello, and thatnks for that package.
There is a comment on persistence.
#24

State persisted only before the page reloaded.
After that, it throws an error


 vue-devtools  Detected Vue v2.6.14 
 {FormWithVerification: accessor {SET_STEP: ...}
 {testVal_1: 'original_val'} // call getter
// call action with mutation within
 {testVal_1: 'mutated_val'} // call getter

// RELOAD PAGE OR REOPEN TAB (SPA)

 {FormWithVerification: accessor {SET_STEP: ...} // same
 {testVal_1: undefined} // call getter
// call action with mutation within throws
unknown action type: FormWithVerificationModule/changeVal
 {testVal_1: undefined} // call getter

I also see state in dev tools, BUT, getters are removed / actions.
Sate not persisted nor dynamic modules registered again.
Its like they were loaded only on the first-page load.

    "vue": "^2.6.14",
    "vue-class-component": "^7.2.3",
    "vue-property-decorator": "^9.1.2",
    "vuex": "^3.0.1",
    "vuex-class": "^0.3.2",
    "vuex-class-modules": "^1.3.0",
    "vuex-multi-tab-state": "^1.0.16",
    "vuex-persistedstate": "^3.2.0",

import Vuex, {ModuleTree}                               from 'vuex';
import Vue                                              from 'vue';

'use strict';
import createPersistedState from 'vuex-persistedstate';
import createMultiTabState  from 'vuex-multi-tab-state';
import SecureLS from 'secure-ls';

const encryptedLocalStorage = new SecureLS(
    {
        encodingType:     'aes',
        encryptionSecret: '****',
        isCompression:    false,
    },
);

const plugins = [
    createMultiTabState(),
    createPersistedState({
                             storage: {
                                 getItem:    key => encryptedLocalStorage.get(key),
                                 setItem:    (key, value) => encryptedLocalStorage.set(key, value),
                                 removeItem: key => encryptedLocalStorage.remove(key),
                             },
                         }),
];

export default plugins;

Vue.use(Vuex);
const store = new Vuex.Store({
        strict:   'production' !== process.env.NODE_ENV,
        devtools: 'production' !== process.env.NODE_ENV,
        modules,
        plugins,
    },
);

export default store;

So, plugins
createMultiTabState(),
createPersistedState()

are not working, reloading page does not register modules again and makes them unavailable for usage.
state resets, getters / actions removed.
Trying to register module again it says module already exists.

Any advice, guidance appreciated. Maybe add some docs on that.
Because cant find in this package such must have feature.
Was thinking to add some beforeDestroy(){} listener or something that will save whole state in local storage, but thats definetely not enough, we need to serialize, encrypt, then restore it back when tab, browser opened or page reloaded.
Thanks!

How to access Store extensions in 'this' instance?

Within vanilla Vuex we have extension like

// vuex-shims.d.ts
declare module 'vuex/types' {
    interface Store<S> {
        $api: ServiceFactory;
    }
}

And access it in actions like

async [ActionNames.DoSomething]() {
  await this.$api.doSomething(); // 'this' known as Store<R> type and $api is registered extension.
}

But module of 'vuex-class-modules' has no 'this' as Store type. How to access $api extension?

Tried to make extended subclass of VuexModule like

export class AugmentedVuexModule extends VuexModule
{
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    protected store: Store<any>;

    constructor(options: RegisterOptions)
    {
        super(options);
        this.store = options.store;
    }
}

Usage:

@Action
async doSomething()
{
    await this.store.$api.doSomething();
}

But it cause an error:

/ -> error during render
RangeError: Maximum call stack size exceeded

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.