簡體   English   中英

vue + Typescript class 組件如何使用mapActions?

[英]How to use mapActions with vue + Typescript class component?

我想知道在 Typescript vue class 組件中使用...mapActions([])的正確方法是什么。

我就是這樣做的:

<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { mapActions } from "vuex";

@Component
export default class UsersAdd extends Vue {
  userName: string = "";

    ...mapActions(["newUser"]) /*mapAction from vuex */
  addUser() {
    console.log("...adding new user");
    this.newUser(this.userName);
  }
}
</script>

正如您所知道的那樣,它不起作用...

使用Javascript我就是這樣做的。

methods:{
  ...mapActions(["newUser"])
}

我怎樣才能用 Typescript class 組件做到這一點?

編輯:我已經嘗試過這種方式,但它仍然無法正常工作

@Component({
  methods: {
    ...mapActions(["newUser"]) /*mapAction from vuex */
  }
})
export default class UsersAdd extends Vue {
  userName: string = "";

  addUser() {
    console.log("...adding new user");
    this.newUser(this.userName);
  }
}

如果您不想引入另一個依賴項(即vuex-class )。 我們可以將 store 中的操作映射到 Typescript 中的組件,如下所示:

@Component({
  computed: {
    ...mapActions({
      someLoadDataAction: "someLoadDataAction"
    })
  }
})
export default class HelloWorld extends Vue {
  someLoadDataAction!: () => any;

  mounted() {
    console.log(this.someLoadDataAction);
  }
}

關鍵是添加這個someLoadDataAction!: () => any用於 Typescript 的靜態類型檢查。 例如,我們將函數類型定義為() => any ,但您可以將其更改為vuex存儲中操作的實際返回類型。

在 Action 注釋的幫助下,您可以通過這種方式執行此操作。 安裝npm install --save vuex-class

import { Action } from 'vuex-class'

@Component()
export default class UsersAdd extends Vue {
  userName: string = "";

  @Action('newUser')
  newUser!: (newUser: string) => void
  addUser() {
    console.log("...adding new user");
    this.newUser(this.userName);
  }
}

另一種方法是使用自定義裝飾器,它將組件中的方法替換為 vuex 存儲中的方法。

function VuexAction(moduleName: string): any {
  return createDecorator((options: any, key: string) => {
    if (!options.methods) options.methods = {};
    options.methods[key] = function wrapperMethod(...args: any[]) {
      return this.$store._actions[`${moduleName}/${key}`][0](...args);
    };
  });
}

裝飾器可以這樣使用:

@Component
export default class SomeComponent extends Vue {
  @VuexAction("vuexModuleName") vuexModuleActionName!: () => void;

  async doStuff () {
    this.vuexModuleActionName();
  }
}

這個想法基於關於自定義裝飾器的文檔:

https://class-component.vuejs.org/guide/custom-decorators.html

還有一個自定義的 vuex getter 裝飾器:

https://github.com/vuejs/vue-class-component/issues/56#issuecomment-272604193

其他選項,您可以使用vuex-module-decorators ,它可以更好地支持typescript並減少代碼。

安裝

npm install -D vuex-module-decorators

存儲/索引.ts

import { Action, getModule, Module, Mutation, VuexModule } from "vuex-module-decorators";
import store from "..";

// define Mutations name
enum Mutations {
  NEW_USER_NAME = "NEW_USER_NAME"   
}

// name: module name
// dynamic: true,dynamic create module
// namespaced: true,using namespaced
// store: your root store/index.ts
@Module({ name: 'UserStore', dynamic: true, namespaced: true, store })
export default class UserStore extends VuexModule {
  // state
  userName = '';

  // mutation
  @Mutation
  [Mutations.NEW_USER_NAME](userName: string) {
    this.userName = userName;
  }

  // action
  @Action
  newUser(userName: string) {
    this.context.commit(Mutations.NEW_USER_NAME, userName);
  }
}

// use getModule to safe get instance
export const userStore = getModule(UserStore);

用戶添加.vue

import { userStore } from "@/store/modules/user";
@Component()
export default class UsersAdd extends Vue {
  userName: string = "";
   
  addUser() {    
    console.log("...adding new user");     
    userStore.newUser(this.userName);
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM