Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example on how to use with Nuxt #89

Open
SandroMaglione opened this issue Nov 6, 2020 · 3 comments
Open

Example on how to use with Nuxt #89

SandroMaglione opened this issue Nov 6, 2020 · 3 comments

Comments

@SandroMaglione
Copy link

I am trying to make the library work with Nuxt.

The docs say that what you need is:

export class UserStore extends createModule({ target: "nuxt" }) {
  ...
}

To test it, I created a new file in the store folder of my Nuxt project. The file contains the class of the example in the docs:

import { createModule, mutation, action } from 'vuex-class-component'

export class UserStore extends createModule({
  strict: false,
  target: 'nuxt'
}) {
  firstname = 'Michael'
  lastname = 'Olofinjana'
  specialty = 'JavaScript'

  @mutation clearName() {
    this.firstname = ''
    this.lastname = ''
  }

  @action async doSomethingAsync() {
    const val1 = await new Promise(() => this.firstname)
    return val1
  }

  @action async doAnotherAsyncStuff(payload: { func: Function }) {
    const number = await this.doSomethingAsync()
    payload.func()
    return payload + this.fullname + number
  }

  // Explicitly define a vuex getter using class getters.
  get fullname() {
    return this.lastname + this.firstname
  }

  // Define a mutation for the vuex getter.
  // NOTE this only works for getters.
  set fullname(name: string) {
    const names = name.split(' ')
    this.firstname = names[0]
    this.lastname = names[1]
  }

  get bio() {
    return `Name: Specialty: ${this.specialty}`
  }
}

I would expect this code to create a new module with the name of the file and relative state (firstname, lastname, specialty), and the getters defined by the class, as well as actions and mutations.

The code compiles, but then the store seems to be empty (from Vuejs devtool):
user: Object (empty), and getter are not present at all.

How can I make it work? Am I missing something?

@swetjen
Copy link

swetjen commented Dec 2, 2020

I think the problem with your code above is here:

export class UserStore extends createModule({ strict: false, target: 'nuxt' }) { ...

Instead it should be like this:

const VuexModule = createModule({
  namespaced: "main",
  strict: false,
  target: "nuxt",
})

export class MainStore extends VuexModule {
   ...

You need to namespace the store.

@michael-scheurer
Copy link

@moifort
Copy link

moifort commented May 2, 2022

Little update, there is a new version of the library. This is my solution, feel free to comment :)

store/user.ts

import { action, createModule, getter, mutation } from 'vuex-class-component'
import { extractVuexModule } from 'vuex-class-component/dist/module'

export class User extends createModule({
  target: 'nuxt',
  enableLocalWatchers: true,
}) {
  private firstname = 'Michael'
  private lastname = 'Olofinjana'
  @getter speciality = 'JavaScript' // The @getter decorator automatically exposes a defined state as a getter.
  @getter occupation = 'Developer'

  static $watch = {
    speciality: (newValue: string) =>
      console.log(`Fullname has changed ${newValue}`),
  }

  static $subscribeAction = {
    doSomethingAsync() {
      console.log(`fetchDetails action was called with payload`)
    },
  }

  @mutation changeName({
    firstname,
    lastname,
  }: {
    firstname: string
    lastname: string
  }) {
    this.firstname = firstname
    this.lastname = lastname
  }

  @action doSomethingAsync() {
    this.speciality = this.$store.app.$vxm.user.firstname
    return Promise.resolve('20')
  }

  @action async doAnotherAsyncStuff(payload: string) {
    const number = await this.doSomethingAsync()
    console.log(number)
    this.changeName({ firstname: 'John', lastname: 'Doe' })
    return payload + this.fullName
  }

  // Explicitly define a vuex getter using class getters.
  get fullName() {
    return this.firstname + ' ' + this.lastname
  }
}

export default Object.values(extractVuexModule(User))[0]

Vue Chrome plugin

Capture d’écran 2022-05-02 à 11 29 41

Accessor Plugin plugins/store.ts

import { Plugin } from '@nuxt/types'
import { createProxy } from 'vuex-class-component'
import { User } from '~/store/user'
import { Car } from '~/store/car'

const createVxm = (store: any) => ({
  user: createProxy(store, User),
  car: createProxy(store, Car),
})

type vxmType = ReturnType<typeof createVxm>

declare module 'vue/types/vue' {
  interface Vue {
    $vxm: vxmType
  }
}

declare module '@nuxt/types' {
  interface NuxtAppOptions {
    $vxm: vxmType
  }
  interface Context {
    $vxm: vxmType
  }
}

const storePlugin: Plugin = ({ store }, inject) => {
  inject('vxm', createVxm(store))
}

export default storePlugin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants