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
相关产品推荐
相关产品推荐

