Nuxt3 + Pinia + VueUse -> useStorage() 不起作用

Arr*_*tch 9 vuejs2 nuxt.js nuxtjs3 pinia vueuse

设置:我使用 Nuxt3 + Pinia + VueUse。

目标: 我想通过 VueUse: 将 pinia 商店的状态保存到本地存储useStorage

问题: 由于某种原因,本地存储中没有创建任何项目。我觉得我在这里错过了一些东西。在组件中我可以useStorage很好地使用。

商店/piniaStoreVueUse.js

import { defineStore } from 'pinia'
import { useStorage } from '@vueuse/core'

export const usePiniaStoreVueUse = defineStore('piniaStoreUseVue', {
    state: () => {
        return { 
            state: useStorage('my-state', 'empty'),
        }
    },
    actions: {
        enrollState() {
            this.state = 'enroll';
        },
        emptyState() {
            this.state = 'empty'; 
        },
    },
    getters: {
    }
});
Run Code Online (Sandbox Code Playgroud)

组件/SampleComponentStatePiniaVueUse.vue

<script lang="ts" setup>
    import { usePiniaStoreVueUse } from '~/stores/piniaStoreVueUse';

    const piniaStoreVueUse = usePiniaStoreVueUse();
</script>

<template>
    <div>
        piniaStoreVueUse.state: {{ piniaStoreVueUse.state }}<br>
        <button class="button" @click="piniaStoreVueUse.enrollState()">
            enrollState
        </button>
        <button class="button" @click="piniaStoreVueUse.emptyState()">
            clearState
        </button>
    </div>
</template>

<style scoped>
</style>
Run Code Online (Sandbox Code Playgroud)

现场版在这里

谢谢。

小智 9

我找到了解决这个问题的方法,而且看起来效果很好。我没有进行广泛的测试,但它似乎有效。

经过大量挖掘后,我在 Pinia 文档中发现了一个页面:处理可组合项

笔记:

npm i -D @vueuse/nuxt @vueuse/core
Run Code Online (Sandbox Code Playgroud)

我测试的代码:

npm i -D @vueuse/nuxt @vueuse/core
Run Code Online (Sandbox Code Playgroud)

test.vue (~~/pages/test.vue)

//storageTestStore.js

import { defineStore, skipHydrate } from "pinia";
import { useLocalStorage } from '@vueuse/core'

export const useStorageTestStore = defineStore('storageTest', {
    state: () => ({
      user: useLocalStorage('pinia/auth/login', 'bob'),
    }),
    actions: {
        setUser(user) {
            this.user = user
        }
    },
  
    hydrate(state, initialState) {
      // in this case we can completely ignore the initial state since we
      // want to read the value from the browser
      state.user = useLocalStorage('pinia/auth/login', 'bob')
    },
  })
Run Code Online (Sandbox Code Playgroud)

浏览器重新加载并在应用程序中导航后,该状态完全保留。


Arr*_*tch 7

我找到了这个问题的答案:

\n

Nuxt3默认使用SSR。但由于 useStorage() (来自 VueUse)使用浏览器本地存储,因此 \xe2\x80\x99 无法工作。

\n

解决方案一:

\n

禁用 SSRnuxt.config.js

\n
export default defineNuxtConfig({\n  ssr: false,\n  \n  // ... other options\n})\n
Run Code Online (Sandbox Code Playgroud)\n

注意:
这会全局禁用 SSR。

\n

解决方案2:

\n

将组件包装在 <client-only placeholder="Loading\xe2\x80\xa6\xe2\x80\x9d> 中

\n
 <client-only placeholder="Loading...">\n    <MyComponent class="component-block"/>\n </client-only>\n
Run Code Online (Sandbox Code Playgroud)\n

我很想知道处理这个问题的其他方法。我觉得应该有更好的办法。

\n

  • 您还可以执行“if (process.client) {”之类的快速检查,以仅应用在前端运行的特定方法。否则,一些生命周期挂钩也[仅在客户端调用](https://nuxtjs.org/pt/docs/concepts/nuxt-lifecycle#nuxt-lifecycle)。 (2认同)

小智 5

我关注这个话题两周了。我解决了使用插件pinia-plugin-persistedstate 的问题。我触摸 plugin/persistedstate.js 并persist: true在 Pinia 中添加 ,defineStore()

首先安装插件yarn add pinia-plugin-persistedstatenpm i pinia-plugin-persistedstate

#plugin/persistedstate.js
import { createNuxtPersistedState } from 'pinia-plugin-persistedstate'

export default defineNuxtPlugin(nuxtApp => {
 nuxtApp.$pinia.use(createNuxtPersistedState(useCookie))
})
Run Code Online (Sandbox Code Playgroud)

#story.js
export const useMainStore = defineStore('mainStore', {
state: () => {
    return {
        todos: useStorage('todos', []),
        ...
    }
},
persist: true, #add this
getters: {...},
actions: {...}
})
Run Code Online (Sandbox Code Playgroud)