在 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 会自动更新。