设计思路
- 集中式缓存管理:使用一个全局的缓存对象来存储所有请求的结果,确保不同组件对相同请求能获取一致数据。
- 缓存标识:根据请求的URL和参数生成唯一的缓存标识,以此来判断缓存中是否已有对应数据。
- 数据更新监听:通过后端推送机制(如WebSocket)或轮询方式,检测数据是否更新。若更新,清除对应缓存,并通知相关组件重新请求数据。
- 组件订阅:组件订阅特定数据的更新,当数据变化时,组件能收到通知并重新获取最新数据。
涉及技术点
- Vuex:用于管理全局状态,存储缓存数据。通过Vuex的状态管理,不同组件可以共享和访问缓存数据。
- Axios:用于发送网络请求。Axios可以方便地拦截请求和响应,进行缓存相关操作。
- WebSocket(可选):用于后端实时推送数据更新消息。若后端支持,使用WebSocket可以更高效地实现数据更新的实时通知。
- Object.freeze():用于冻结缓存数据,防止在组件中意外修改缓存数据。
关键代码实现
- Vuex模块定义
// store/modules/cache.js
const state = {
cache: {}
};
const mutations = {
SET_CACHE(state, { key, data }) {
state.cache[key] = data;
},
CLEAR_CACHE(state, key) {
if (state.cache[key]) {
delete state.cache[key];
}
}
};
const actions = {
async fetchData({ commit, state }, { url, params }) {
const key = `${url}-${JSON.stringify(params)}`;
if (state.cache[key]) {
return state.cache[key];
}
try {
const response = await axios.get(url, { params });
commit('SET_CACHE', { key, data: response.data });
return response.data;
} catch (error) {
console.error('Error fetching data:', error);
throw error;
}
}
};
export default {
namespaced: true,
state,
mutations,
actions
};
- Axios拦截器
import axios from 'axios';
import store from '@/store';
axios.interceptors.request.use(config => {
const { url, params } = config;
const key = `${url}-${JSON.stringify(params)}`;
const cachedData = store.state.cache.cache[key];
if (cachedData) {
return Promise.reject({ response: { data: cachedData } });
}
return config;
});
axios.interceptors.response.use(response => {
const { url, params } = response.config;
const key = `${url}-${JSON.stringify(params)}`;
store.commit('cache/SET_CACHE', { key, data: response.data });
return response;
});
- 组件使用
<template>
<div>
<button @click="fetchData">获取数据</button>
<div v-if="data">{{ data }}</div>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
methods: {
...mapActions('cache', ['fetchData'])
},
async created() {
try {
const data = await this.fetchData({ url: '/api/product', params: { fields: 'name,price' } });
this.data = data;
} catch (error) {
console.error('Error in component:', error);
}
}
};
</script>
- 数据更新通知(以WebSocket为例)
// 在main.js或单独的服务文件中
import store from '@/store';
const socket = new WebSocket('ws://your-server-url');
socket.onmessage = (event) => {
const { url, params } = JSON.parse(event.data);
const key = `${url}-${JSON.stringify(params)}`;
store.commit('cache/CLEAR_CACHE', key);
// 这里可以添加通知相关组件重新获取数据的逻辑,例如通过Vue的事件总线
};