使用TypeScript+Vuex

準備工做

1,使用vue-cli 3搭建Vue項目,若是不知道怎麼搭建的同窗能夠點擊這裏vue

2,使用 npm i -s vuex-class 命令安裝 vuex-classvuex

3,刪除src/store.ts(很重要)vue-cli

4,根目錄下新建以下文件typescript


5,代碼以下npm

store/types.ts bash

  • 聲明並暴露 RootState 類型
// store/types.ts

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

export interface RootState {
  user: UserState
}複製代碼


store/index.tspost

  • 使用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.tsfetch

  • 聲明並暴露UserState類型

// store/user/types.ts

export interface UserState {
  firstName: string
  lastName: string
  mobile: string
}複製代碼


store/user/actions.tsui

  • 使用ActionTree定義actions的類型,並將UserStateRootState做爲泛型傳入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.tsthis

  • 使用GetterTree定義getters的類型,並將UserStateRootState做爲泛型傳入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模塊的類型,並將UserStateRootState做爲泛型傳入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
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
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
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')
  }
}複製代碼

參考:codeburst.io/vuex-and-ty…

相關文章
相關標籤/搜索