乐趣区

使用TypeScriptVuex

准备工作

1,使用 vue-cli 3 搭建 Vue 项目,如果不知道怎么搭建的同学可以点击这里

2,删除 src/store.ts(很重要)

3,根目录下新建如下文件

4,代码如下

store/types.ts

  • 声明并暴露 RootState 类型
// store/types.ts

import {UserState} from './user/types'

export interface RootState {user: UserState}


store/index.ts

  • 使用 StoreOptions 类型定义 Vuex.Store 构造器选项的类型,并将 RootState 作为泛型传入 StoreOptions,用来定义根状态的类型
  • 将 RootState 作为泛型,传入 Vuex.Store 构造器
// store/index.ts

import Vue from 'vue'
import Vuex, {StoreOptions} from 'vuex'
import {RootState} from './types'
import {user} from './user/index'Vue.use(Vuex)

const store: StoreOptions<RootState> = {
  modules: {user}
}
export default new Vuex.Store<RootState>(store)


store/user/types.ts

  • 声明并暴露 UserState 类型
// store/user/types.ts

export interface UserState {
  firstName: string
  lastName: string
  mobile: string
}


store/user/actions.ts

  • 使用 ActionTree 定义 actions 的类型,并将 UserState 和 RootState 作为泛型传入 ActionTree
// store/user/actions.ts

import {UserState} from './types'
import {ActionTree} from 'vuex'
import {RootState} from '../types'

export const actions: ActionTree<UserState, RootState> = {fetchData({ commit}): void {
    const userInfo: UserState = {
      firstName: 'Hello',
      lastName: 'World',
      mobile: '1235678911'
    }
    commit('saveUserInfo', userInfo)
  }
}


store/uset/getters.ts

  • 使用 GetterTree 定义 getters 的类型,并将 UserState 和 RootState 作为泛型传入 GetterTree
// store/user/getters.ts

import {GetterTree} from 'vuex'
import {UserState} from './types'
import {RootState} from '../types'

export const getters: GetterTree<UserState, RootState> = {fullName(state): string {return `${state.firstName} ${state.lastName}`
  }
}


store/user/mutations.ts

  • 使用 MutationTree 定义 mutations 的类型,并将 UserState 作为泛型传入 MutationTree
  • MutationTree 不需要传入 RootState
// store/user/mutations.ts

import {MutationTree} from 'vuex'
import {UserState} from './types'

export const mutations: MutationTree<UserState> = {changeMobile(state, mobile: string) {state.mobile = mobile},
  saveUserInfo(state, userInfo) {state = Object.assign(state, userInfo)
  }
}


store/user/index.ts

  • 使用 UserState 定义 user 模块的 state 的类型
  • 使用 Module 定义 user 模块的类型,并将 UserState 和 RootState 作为泛型传入 Module
// store/user/index.ts

import {Module} from 'vuex'
import {UserState} from './types'
import {RootState} from '../types'
import {getters} from './getters'
import {actions} from './actions'
import {mutations} from './mutations'

const state: UserState = {
  firstName: '',
  lastName: '',
  mobile: ''
}
const namespaced = true
export const user: Module<UserState, RootState> = {
  namespaced,
  state,
  getters,
  actions,
  mutations
}
export default state

开始使用

1,使用 namespace('path/to/module') 装饰器

import {Component, Vue} from 'vue-property-decorator'
import {namespace} from 'vuex-class'

const userModule = namespace('user')

@Component({
  components: {HelloWorld}
})
export default class Home extends Vue {@userModule.Action('fetchData') public fetchData!: Function
  @userModule.Mutation('changeMobile') public changeMobile!: Function
  @userModule.Getter('fullName') public fullName!: string
  @userModule.State('firstName') public firstName!: string
  @userModule.State('mobile') public mobile!: string
  public created() {this.fetchData()
    this.changeMobile('123456')
  }
}

等同于使用下面的 js 写法:

import {createNamespacedHelpers} from 'vuex'

const {
  mapState,
  mapMutations,
  mapGetters,
  mapActions
} = createNamespacedHelpers('user')

export default {
  computed: {...mapState(['firstName', 'mobile']),
    ...mapGetters(['fullName'])
  },
  methods: {...mapActions(['fetchData']),
    ...mapMutations(['changeMobile'])
  },
  created() {this.fetchData()
    this.changeMobile('123456')
  }
}

2,使用 @Action('action', { namespace: 'path/to/module'}) 这种形式

import {Component, Vue} from 'vue-property-decorator'
import {Action, Mutation, Getter, State} from 'vuex-class'

const namespace = 'user'
@Component({
  components: {HelloWorld}
})
export default class Home extends Vue {@Action('fetchData', { namespace}) public fetchData!: Function
  @Mutation('changeMobile', { namespace}) public changeMobile!: Function
  @Getter('fullName', { namespace}) public fullName!: string
  @State('firstName', { namespace}) public firstName!: string
  @State('mobile', { namespace}) public mobile!: string

  public created() {this.fetchData()
    this.changeMobile('123456')
  }
}

3,使用 @Action('path/to/module/action') 这种形式

注意:@State装饰器不能使用这种方式

import {Component, Vue} from 'vue-property-decorator'
import {Action, Mutation, Getter, State} from 'vuex-class'

const namespace = 'user'
@Component({
  components: {HelloWorld}
})
export default class Home extends Vue {@Action('user/fetchData') public fetchData!: Function
  @Mutation('user/changeMobile') public changeMobile!: Function
  @Getter('user/fullName') public fullName!: string
  @State('firstName', { namespace}) public firstName!: string
  @State('mobile', { namespace}) public mobile!: string

  public created() {this.fetchData()
    this.changeMobile('123456')
  }
}

参考:https://codeburst.io/vuex-and…

退出移动版