Vue3 + Typescript builds Vuex modularity very differently than the Vue2 project does.

Install vuex – module – decorators

This is an NPM package that helps us build Vuex modules quickly, safely and efficiently.

npm install vuex-module-decorators
# or
yarn add vuex-module-decorators
Copy the code

In Vue CLI created projects, remember to add translation configuration (ES6 to ES5) in vue.config.js configuration and be IE11 compatible.

// vue.config.js
module.exports = {
  // ... your other options
  transpileDependencies: [
    'vuex-module-decorators']}Copy the code

Usage,

state

// store/modules/user.js
import { Module, VuexModule, Mutation, Action, getModule } from 'vuex-module-decorators'
import store from '@/store'

@Module({ dynamic: true, store, name: 'user' })
class User extends VuexModule {
  count = 20
}
export const UserModule = getModule(User)
Copy the code

Equivalent to the following

export default {
	state: {
		count: 20}}Copy the code

If you cannot determine the status value, then you must give it an initial value is null, he like this count: number | null = null

getters

// store/modules/user.js
import { Module, VuexModule, Mutation, Action, getModule } from 'vuex-module-decorators'
import store from '@/store'

@Module({ dynamic: true, store, name: 'user' })
class User extends VuexModule {
	count = 20
	get halfCount() {
		return this.count / 2}}export const UserModule = getModule(User)
Copy the code

Equivalent to the following

export default {
	state: {
		count: 20
	},
	getters: {
		halfCount: state= > state.count / 2}}Copy the code

How about if you want to process some complex data in Getters

// store/modules/user.js
@Module({ dynamic: true, store, name: 'user' })
class User extends VuexModule {
  companies = []
  get company() {
    return (companyName: string) = > { this.companies.find(company= >company.name === companyName) }; }}Copy the code

mutations

// store/modules/user.js
import { Module, VuexModule, Mutation } from 'vuex-module-decorators'

@Module({ dynamic: true, store, name: 'user' })
class User extends VuexModule {
  count = 20

  @Mutation
  REDUCE_COUNT(payload: number) {
    this.count = this.count - payload
  }
}
export const UserModule = getModule(User)
Copy the code

Equivalent to the following

export default {
	state: {
    	count: 20
  	},
	mutations: {
	   REDUCE_COUNT: (state, payload) = > {
	     state.count = state.count - payload
	   }
	}
}
Copy the code

Use this to refer to state

actions

// store/modules/user.js
@Module({ dynamic: true, store, name: 'user' })
class User extends VuexModule {
	@Action
  	dispatchReduce(payload: number) {
    	this.context.commit('REDUCE_COUNT', payload)
  	}
}
export const UserModule = getModule(User)
Copy the code

Equivalent to the following

export default {
	state: {
    	count: 20
  	},
	actions: {
	   REDUCE_COUNT: ({ commit }, payload) = > {
	     commit('REDUCE_COUNT', payload)
	   }
	}
}
Copy the code

MutationActions

For the same reason welcome to the documentation

Use in a file

The first kind of

Class User extends VuexModule{} export const UserModule = getModule(User)

// store/modules/user.js
import { Module, VuexModule, Mutation, Action, getModule } from 'vuex-module-decorators'
import store from '@/store'

@Module({ dynamic: true, store, namespaced: true.name: 'user' })

class User extends VuexModule {
	// TODO
}
export const UserModule = getModule(User)
Copy the code
// store/index.ts
import { createStore } from 'vuex'

export default createStore({})
Copy the code
<! -- index.vue --->
<template>
  <div class="home">
    <h1 class="text">Home</h1>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { UserModule } from '@/store/modules/user'

export default defineComponent({
  name: 'Home'.setup() {
    const myhalfCount = UserModule.halfCount
    UserModule.dispatchReduce(5)

    console.log(myhalfCount) / / 10
    console.log(UserModule.count) / / 15
  },
  components: {}})</script>

Copy the code

The second,

@module ({store, namespaced: true, name) {store, namespaced: true, name: ‘user’ }) export default class User extends VuexModule{}

// store/modules/user.js
import { Module, VuexModule, Mutation, Action, getModule } from 'vuex-module-decorators'
import store from '@/store'

@Module({ store, namespaced: true.name: 'user' })

export default class User extends VuexModule {
	// TODO
}
Copy the code
// store/index.ts
import { createStore } from 'vuex'
import UserModule from '~/store/modules/user'

export default createStore({
  modules: {
    user: UserModule // The key name must be the same as the @module name}})Copy the code
<! -- index.vue --->
<template>
  <div class="home">
    <h1 class="text">Home</h1>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import store from '@/store'

export default defineComponent({
  name: 'Home'.setup() {
    console.log(store.state.user.count) / / 20
  },
  components: {}})</script>
Copy the code

The authors recommend the first approach