You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中如何实现sessionStorage的响应式效果?

问题背景

我开发了一款应用,最初每次加载或刷新页面时都会通过axios.get从数据库拉取数据,导致应用运行缓慢,因此打算仅在应用的*首次加载(initial load)*阶段获取数据并存入sessionStorage。

但sessionStorage本身不具备响应性,我最初的代码写法如下:

const state = reactive({
    image: sessionStorage.image
})

模板渲染逻辑:

<div class="home-image" :style="{'background-image': 'url(' + state.image + ')'}"></div>

这段代码只有在上一次页面加载时已经更新过sessionStorage的场景下才能正常运行,首次页面加载时state.image会抛出404 not found错误。我查阅了watchers、set和get的相关资料,暂时没有找到可行的实现方案。


新解决方案(无需Vuex)

我最终找到了一种不需要引入vuex,就能让sessionStorage在首次加载阶段表现出reactive特性的实现方法:

<script setup>
import {reactive} from 'vue';

const state = reactive({
    image: sessionStorage.image || ""
})

axios.get('/home')
    .then(res => {
        const data = res.data[0]
        state.image = sessionStorage.image = 'storage/' + data['image']
    })
</script>

实现逻辑:reactive初始化时如果sessionStorage的image为undefined,会优先使用空字符串作为默认值,等axios.get请求拿到返回数据后,同步给响应式状态state.image和sessionStorage.image赋值。后续所有页面加载时,reactive会直接读取sessionStorage中已经存储好的值,不需要重复发送请求。

编码很有乐趣,有时你能找到用1行代码替代100行代码的方法。


旧解决方案(基于Vuex实现)

这个方案实现的存储具备全局(global)、响应式(reactive)、*持久化(persistent)*三个特性,使用便捷。

步骤1:创建独立store文件

在store.js中定义全局存储:

import {createStore} from "vuex";

const store = createStore({
    state() {
        return {
            image: sessionStorage.image || ""
        }
    }
})
export default store

步骤2:全局注册store

在app.js中注册刚才创建的store:

require('./bootstrap');

import {createApp} from 'vue';
import app from "../vue/app";
import store from "./store";

createApp(app)
    .use(store)
    .mount("#app");

步骤3:组件中使用

<template>
  <section id="home" class="home">
    <div class="image-container">
      <div class="home-image" :style="{'background-image': 'url(' + store.state.image + ')'}"></div>
    </div>
  </section>
</template>


<script setup>
import {useStore} from "vuex";

const store = useStore()

if (!sessionStorage.image) {
    axios.get('/home')
        .then(res => {
            const data = res.data[0]
            store.state.image = sessionStorage.image = 'storage/' + data['image']
        })
}
</script>

方案说明

axios请求仅在sessionStorage.image为undefined时才会触发,否则会直接读取sessionStorage中存储的值渲染。如果存储的图片链接有效,图片不会在模板中重新加载,直接瞬间渲染完成。

使用该方案不需要再单独写state = reactive的声明,直接全局使用store.state即可,也可以扩展关联sessionStorage或者localStorage,只需要维护store中的字段定义就行。如果不给state字段加空字符串默认值,Vue会抛出404 errors(不过因为响应式特性,等数据返回后元素最终还是会正常渲染)。


内容的提问来源于stack exchange,提问作者Artur Müller Romanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:06:07