You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue如何将组件内方法迁移至store文件并在组件调用

1. TestStore.js 重构实现

把异步请求逻辑放到Vuex的actions中,状态修改统一走mutations,相关响应式状态收敛到state中,完整实现参考如下:

// 引入路径按你项目实际配置调整
import axios from 'axios'
import Helper from '@/utils/Helper'
const collect = require('collect.js')

export default {
  // 开启命名空间做模块隔离,调用时需要带模块名
  namespaced: true,
  state: () => ({
    isSearching: false,
    suggestedUsers: [],
    suggestedUsersData: {
      page: 1,
      perPage: 10,
      total: 0
    },
    // 请求取消凭证
    requestToken: {
      token: null,
      cancel: null
    }
  }),
  mutations: {
    SET_SEARCH_STATUS(state, status) {
      state.isSearching = status
    },
    APPEND_SUGGESTED_USERS(state, userList) {
      collect(userList).each((user) => {
        if (!state.suggestedUsers.some(obj => obj.id === user.id)) {
          state.suggestedUsers.push(user)
        } else if (
          user.project_specific_job_title_id &&
          !state.suggestedUsers.some(obj => obj.project_specific_job_title_id === user.project_specific_job_title_id)
        ) {
          state.suggestedUsers.push(user)
        }
      })
    },
    UPDATE_PAGINATION(state, { per_page, total }) {
      state.suggestedUsersData.perPage = per_page
      state.suggestedUsersData.total = total
    },
    UPDATE_REQUEST_TOKEN(state, tokenSource) {
      state.requestToken = tokenSource
    },
    // 可选:重置列表用
    RESET_SUGGESTED_USERS(state) {
      state.suggestedUsers = []
      state.suggestedUsersData.page = 1
    }
  },
  actions: {
    // payload接收组件传入的动态参数
    async loadSuggestedUsers({ commit, state }, payload) {
      const { suggestionUrl, searchText, selectedNationalities, page } = payload
      
      if (!suggestionUrl) return false
      commit('SET_SEARCH_STATUS', true)

      // 取消上一次未完成的重复请求
      if (state.requestToken.cancel) {
        state.requestToken.cancel('cancel previous request')
      }
      // 生成新的请求取消凭证
      const { token, cancel } = axios.CancelToken.source()
      commit('UPDATE_REQUEST_TOKEN', { token, cancel })

      try {
        const { data } = await axios.get(`/${Helper.getLocale()}/dashboard/${suggestionUrl}`, {
          params: {
            page: page || state.suggestedUsersData.page,
            per_page: state.suggestedUsersData.perPage,
            search_text: searchText,
            nationality: selectedNationalities
          },
          cancelToken: token
        })

        commit('APPEND_SUGGESTED_USERS', data.data)
        commit('UPDATE_PAGINATION', {
          per_page: data.per_page,
          total: data.total
        })
        commit('SET_SEARCH_STATUS', false)
        return data
      } catch (error) {
        if (error instanceof axios.Cancel) return false
        commit('SET_SEARCH_STATUS', false)
        throw error
      }
    }
  }
}

注意:如果suggestionUrl/searchText/selectedNationalities属于全局共享状态,也可以直接放到state中管理,不用每次通过payload传入,按实际业务场景调整即可。写完后记得在Vuex store入口文件(一般是store/index.js)中注册这个TestStore模块。


2. 组件中调用store方法

分两种常用写法,注意如果注册TestStore时自定义的模块名不是test,把代码里的test替换成你实际用的模块名即可;如果没开命名空间,直接省略test/前缀。

选项式API写法(Vue2/Vue3兼容)

通过computed映射store状态,用dispatch触发action即可,也可以用vuex提供的辅助函数简化代码:

<script>
import { mapState, mapActions } from 'vuex'
export default {
  computed: {
    // 映射store中的状态,不用在data里重复定义
    ...mapState('test', ['isSearching', 'suggestedUsers', 'suggestedUsersData'])
  },
  methods: {
    // 映射store中的action
    ...mapActions('test', ['loadSuggestedUsers']),
    // 原来触发加载的逻辑,比如滚动加载、搜索输入触发
    async handleLoadUsers() {
      await this.loadSuggestedUsers({
        suggestionUrl: this.suggestionUrl, // 组件本地变量直接从this取
        searchText: this.searchText,
        selectedNationalities: this.selectedNationalities,
        page: this.suggestedUsersData.page
      })
    }
  }
}
</script>

组合式API写法(Vue3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:57:26