我在制作网页时遇到一个问题:在多个Vue组件中频繁调用同一个接口/company/info,导致重复请求,想要减少访问次数。
首先,我需要分析问题的根源。在首页、底部组件以及其他页面都调用了这个接口,每次组件加载时都会发起请求,这样确实会造成资源浪费,尤其是在数据不常变化的情况下。
使用Vuex进行状态管理是一个不错的选择。将公司信息存储在全局状态中,各个组件通过状态获取数据,而不是各自发起请求。这需要设置Vuex的store,创建一个模块来管理公司信息的状态、actions和mutations。当应用初始化时,或者在需要的时候,触发一次数据获取,之后所有组件都从store中读取数据,避免重复请求。
下面是实施步骤:
1.安装Vuex(如果尚未安装)
npm install vuex --save
2.创建store模块
在路径src/store/modules新建company.js文件,加入下面代码
import request from '@/utils/request'
const state = {
info: null,
lastFetch: 0
}
const mutations = {
SET_COMPANY_INFO: (state, info) => {
state.info = info
state.lastFetch = Date.now()
}
}
const actions = {
async fetchCompanyInfo ({ commit, state }) {
const shouldFetch = !state.info || (Date.now() - state.lastFetch > 3600_000)
console.log('缓存状态:', {
hasInfo: !!state.info,
lastFetch: new Date(state.lastFetch).toLocaleTimeString(),
shouldFetch
})
if (shouldFetch) {
try {
// console.log('发起请求:', request.defaults.baseURL + '/company/info') // 修正变量名
const res = await request.get('/company/info')
console.log('请求成功:', res)
commit('SET_COMPANY_INFO', res)
} catch (error) {
console.error('完整错误对象:', error)
console.error('错误栈:', error.stack)
commit('SET_COMPANY_INFO', {
name: '默认公司',
description: `数据加载失败: ${error.message}`
})
}
}
return state.info
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
注意:这部分代码前提是我封装了axios请求在request.js文件中
3.在根store中注册模块
找到store下的index.js,没有的话可以新建
// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import company from './modules/company'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
company
}
})
4.在App.vue初始化数据
<script>
export default {
created () {
this.$store.dispatch('company/fetchCompanyInfo')
}
}
</script>
5.在需要的地方引用
有三种使用方法,第一种:使用mapState辅助函数
import { mapState } from 'vuex'
export default {
computed: {
...mapState('company', ['info'])
},
mounted() {
console.log(this.info) // 直接访问缓存数据
}
}
第二种:使用getter实时获取
export default {
computed: {
companyInfo() {
return this.$store.state.company.info
}
}
}
第三种:强制刷新数据(需要时使用)
// 在需要更新缓存时调用
this.$store.dispatch('company/fetchCompanyInfo', { force: true }).then(info => {
// 获取最新数据
})
数据加载流程: