面试题答案
一键面试实现思路
- 事件总线:利用浏览器的
window.postMessage
方法创建一个简单的事件总线。当一个标签页中的状态发生变化时,通过postMessage
发送消息给其他标签页,其他标签页监听该消息并更新自己的状态。 - 共享存储:使用
localStorage
或sessionStorage
作为共享存储。当状态变化时,同时更新存储,其他标签页监听存储变化事件,获取最新状态。但要注意处理好存储事件在同一标签页内多次触发等问题。 - WebSockets:建立一个WebSocket连接,各个标签页都连接到同一个WebSocket服务器。当状态改变时,通过WebSocket将变化推送给所有连接的标签页,实现状态同步。
技术手段举例
- 使用window.postMessage:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
// 发送消息
function sendMessageToOtherTabs(data) {
window.open('', '_blank').close(); // 确保至少有两个标签页
window.postMessage(data, '*');
}
// 监听消息
window.addEventListener('message', function(event) {
if (event.origin === window.location.origin) {
// 处理接收到的状态数据,更新Pinia状态
console.log('Received data:', event.data);
}
});
// 假设这里是Pinia状态变化时触发的逻辑
const piniaStateChange = () => {
const stateData = { /* 这里获取Pinia中的状态数据 */ };
sendMessageToOtherTabs(stateData);
};
</script>
</body>
</html>
- 使用localStorage:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
// 监听localStorage变化
window.addEventListener('storage', function(event) {
if (event.key === 'pinia-state' && event.storageArea === localStorage) {
const newState = JSON.parse(event.newValue);
// 更新Pinia状态
console.log('Received new state from localStorage:', newState);
}
});
// 假设这里是Pinia状态变化时触发的逻辑
const piniaStateChange = () => {
const stateData = { /* 这里获取Pinia中的状态数据 */ };
localStorage.setItem('pinia-state', JSON.stringify(stateData));
};
</script>
</body>
</html>
- 使用WebSockets:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
const socket = new WebSocket('ws://your-server-url');
socket.addEventListener('message', function(event) {
const newState = JSON.parse(event.data);
// 更新Pinia状态
console.log('Received new state from WebSocket:', newState);
});
// 假设这里是Pinia状态变化时触发的逻辑
const piniaStateChange = () => {
const stateData = { /* 这里获取Pinia中的状态数据 */ };
socket.send(JSON.stringify(stateData));
};
</script>
</body>
</html>
在Vue应用中,结合Pinia,可以在store的 actions
或 mutations
中触发这些同步逻辑,确保各个标签页间状态同步且避免冲突。