有啥方法可以让 Vue3 中的 sessionStorage 响应式?
Posted
技术标签:
【中文标题】有啥方法可以让 Vue3 中的 sessionStorage 响应式?【英文标题】:Any way to make sessionStorage reactive in Vue3?有什么方法可以让 Vue3 中的 sessionStorage 响应式? 【发布时间】:2021-12-15 17:29:54 【问题描述】:假设我构建了一个应用程序,它每次加载或刷新时都会通过 axios.get
从数据库中获取数据。这让app变慢了,所以我只想把app的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
。
有没有办法让sessionStorage
反应?我读过关于watchers
、set
和get
的文章,但不太明白。
解决方案(新):
Aaaa 实际上,我刚刚找到了一种方法,可以让 sessionStorage
在 initial load
期间表现得就像是 reactive
,而我什至不需要 vuex
:
<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
在初始加载期间未定义并将值从axios.get
分配给sessionStorage
。在所有连续的页面加载中,reactive
函数使用 sessionStorage
,它现在已经分配了一个值。
编码很有趣。有时您会学习如何用 1 个 LOC 替换 100 行代码。
解决方案(旧):
好的,现在我的存储按我想要的方式工作。它是global
、reactive
、persistent
,易于使用。我会接受@Elsa 的回答,因为她帮我调查了vuex
。
我在单独的 store.js
文件中创建了一个store
:
import createStore from "vuex";
const store = createStore(
state()
return
image: sessionStorage.image || ""
)
export default store
然后在app.js
注册:
require('./bootstrap');
import createApp from 'vue';
import app from "../vue/app";
import store from "./store";
createApp(app)
.use(store)
.mount("#app");
现在我可以在我的组件中使用store
,如下所示:
<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
未定义时运行,否则直接呈现其值。如果链接存在,则图像不会首先在模板中新加载,而是立即渲染。
我现在可以完全省略state = reactive
,因为我可以在全局范围内使用store.state
,甚至可以将其链接到ss/ls
。我唯一需要维护的是里面的字段:
const store = createStore(
state()
return
image: sessionStorage.image || ""
)
因为如果我不这样做,vue
会抛出 404 errors
(但由于反应性,无论如何都会渲染元素)。
【问题讨论】:
不,您不能以这种方式使 sessionStorage 反应。但是,这确实是 Vuex! 的用例! 为什么不使用提供和注入? @huanfeng 我更喜欢使用global reactive storage
【参考方案1】:
首先,sessionStorage 不能是响应式的。
如果我的理解正确,您只希望全局变量具有反应性。你可以简单地通过提供和注入来实现它:
const yourGlobalVar = sessionStorage.getItem('image');
app.provide('yourImage', ref(yourGlobalVar))
用在哪里:
setup()
...
const image = inject('yourImage');
...
return image
【讨论】:
我的主要问题是我需要一个persistent variable
,它也可以使用reactively
。如果没有sessionStorage/localStorage
,我不知道如何实现这一点。似乎有一种方法可以在composition api
中创建global variables
并传递它们,但似乎没有办法让它们成为persistent
。
您可以添加一个层来提供一个get/set,每次从存储中获取数据并更改全局变量的值之后,以及在将数据设置到存储之前,更新全局变量。跨度>
【参考方案2】:
我一周前遇到了这个问题,我尝试了 3 种方法在 vue3 中使 sessionStorage 响应式。 1.vuex 2.创建事件监听器 3.设置间隔
我找到了解决 setInterval 问题的临时解决方案。
1.vuex
const state = () =>
return
latInfo: sessionStorage.getItem('lat') || 0
const getters =
latInfo: state => state.latInfo
3.setInterval
setup()
setInterval(() =>
if (infoData)
infoData.lat = sessionStorage.getItem('lat')
, 1000)
【讨论】:
欢迎您。是的,我看了你的解决方案。这个问题有几种解决方案。老实说,我必须为我的项目使用 setInterval,因为我需要将脚本部分反应到 html 页面中。我很高兴能够帮助您解决我的问题。以上是关于有啥方法可以让 Vue3 中的 sessionStorage 响应式?的主要内容,如果未能解决你的问题,请参考以下文章