【发布时间】: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
标签: javascript html vue.js vuejs3 session-storage