在 Vue 3 中,监听 sessionStorage 的变化可以通过几种方式实现,但值得注意的是,原生 sessionStorage 事件并不直接支持变化监听。这意味着你不能直接像监听 window.localStorage 那样使用 storage 事件来监听 sessionStorage 的变化。不过,你可以通过轮询(polling)或者使用 Proxy 对象来间接实现监听。
# 方法 1:使用轮询(Polling)
轮询是一种简单的方法,通过定期检查 sessionStorage 的内容是否发生变化来实现。
| <script setup> | |
| import { ref, onMounted, onUnmounted } from 'vue'; | |
| const checkSessionStorage = () => { | |
| const initialData = sessionStorage.getItem('yourKey'); | |
| const interval = setInterval(() => { | |
| const currentData = sessionStorage.getItem('yourKey'); | |
| if (currentData !== initialData) { | |
|       // 执行你的逻辑 | |
| console.log('sessionStorage changed!'); | |
| initialData = currentData; // 更新初始值 | |
|     } | |
| }, 1000); // 检查频率,例如每秒检查一次 | |
| onUnmounted(() => { | |
| clearInterval(interval); | |
| }); | |
| } | |
| onMounted(() => { | |
| checkSessionStorage(); | |
| }); | |
| </script> | 
# 方法 2:使用 Proxy 对象
另一种更现代的方法是使用 Proxy 对象来创建一个代理,该代理可以捕获对 sessionStorage 的任何更改。然而,这种方法有其局限性,因为 Proxy 不能直接代理全局的 sessionStorage 对象,但你可以创建一个包装器来模拟这一行为。
| <script setup> | |
| import { ref, onMounted, onUnmounted } from 'vue'; | |
| const proxySessionStorage = new Proxy({}, { | |
| get(target, prop) { | |
| return sessionStorage.getItem(prop); | |
| }, | |
| set(target, prop, value) { | |
| const oldValue = sessionStorage.getItem(prop); | |
| if (value !== oldValue) { | |
| sessionStorage.setItem(prop, value); | |
|       // 执行你的逻辑 | |
| console.log('sessionStorage changed!'); | |
|     } | |
| return true; // 表示成功设置值 | |
|   } | |
| }); | |
| onMounted(() => { | |
|   // 现在你可以通过 proxySessionStorage 来访问和监听 sessionStorage 的变化 | |
| proxySessionStorage.yourKey = 'newValue'; // 示例设置值并触发监听 | |
| }); | |
| </script> | 
# 方法 3:使用 window.addEventListener 监听 storage 事件
| <template> | |
| <!-- existing template code --> | |
| </template> | |
| <script setup> | |
| import { ref, computed, onMounted, onUnmounted } from 'vue' | |
| import { session } from '@/utils/storage' | |
| const basketStore = ref(session.get('basket') || []) | |
| const isCart = computed(() => basketStore.value.length > 0) | |
| const rowConfig = { | |
| useKey: true, | |
| isCurrent: true, | |
| isHover: true, | |
| } | |
| const columnConfig = { | |
| resizable: true, | |
| } | |
| const treeConfig = { | |
| transform: true, | |
| rowField: 'id', | |
| parentField: 'parentId', | |
| showLine: true, | |
| expandAll: true, | |
| } | |
| const tableData = [ | |
|   // existing table data | |
| ] | |
| const addToCart = row => { | |
| const updatedBasket = [...basketStore.value, row] | |
| session.set('basket', updatedBasket) | |
| basketStore.value = updatedBasket | |
| } | |
| const handleStorageChange = event => { | |
| if (event.key === 'basket') { | |
| basketStore.value = JSON.parse(event.newValue) || [] | |
|   } | |
| } | |
| onMounted(() => { | |
| window.addEventListener('storage', handleStorageChange) | |
| }) | |
| onUnmounted(() => { | |
| window.removeEventListener('storage', handleStorageChange) | |
| }) | |
| </script> | |
| <style lang="scss" scoped> | |
| /* existing style code */ | |
| </style> | 
在这个示例中,我们使用 ref 来存储 basketStore ,并在组件挂载时添加 storage 事件监听器,在组件卸载时移除监听器。这样,当 sessionStorage 中的 basket 发生变化时, basketStore 会自动更新。
