uni-app vue3 pinia使用持久化插件在快手小程序中报错“Cannot read property 'getItem' of undefined”

发布于 1周前 作者 bupafengyu 来自 Uni-App

uni-app vue3 pinia使用持久化插件在快手小程序中报错“Cannot read property ‘getItem’ of undefined”

示例代码:

import { createPinia } from 'pinia';  
import piniaPersist from 'pinia-plugin-persist-uni';  

const pinia = createPinia();  
pinia.use(piniaPersist);  

export default pinia;
import App from './App';  
import { createSSRApp } from 'vue';  
import uviewPlus from 'uview-plus';  
import pinia from "@/stores/index.js";  

export function createApp() {  
  const app = createSSRApp(App);  
    app.use(pinia);  
    app.use(uviewPlus);  

    let $my = {};  
    uni.$my = $my;  
  app.config.globalProperties.$my = $my;  

    // uni.$u.config.unit = 'rpx';  
  return {  
    app,  
  }  
}

操作步骤:

在快手小程序中使用pinia-plugin-persist-uni作为pinia持久化插件

预期结果:

无报错,正常使用pinia持久化

实际结果:

报错
TypeError: Cannot read property 'getItem' of undefined  
    at vendor.js:10812  
    at Array.forEach (<anonymous>)  
    at index (vendor.js:10806)  
    at vendor.js:7475  
    at EffectScope.run (vendor.js:1579)  
    at vendor.js:7475  
    at Array.forEach (<anonymous>)  
    at createSetupStore (vendor.js:7464)  
    at createOptionsStore (vendor.js:7166)  
    at Object.useStore [as useFloatStore] (vendor.js:7524)

bug描述:

使用uniapp vue3 pinia并配置pinia-plugin-persist-uni持久化插件后报错,具体信息如下:

TypeError: Cannot read property 'getItem' of undefined  
    at vendor.js:10812  
    at Array.forEach (<anonymous>)  
    at index (vendor.js:10806)  
    at vendor.js:7475  
    at EffectScope.run (vendor.js:1579)  
    at vendor.js:7475  
    at Array.forEach (<anonymous>)  
    at createSetupStore (vendor.js:7464)  
    at createOptionsStore (vendor.js:7166)  
    at Object.useStore [as useFloatStore] (vendor.js:7524)
开发环境 版本号 项目创建方式
Windows 22H2 HBuilderX

4 回复

感谢反馈,目前你可以通过使用 https://gitcode.net/xiurensha5731/uni-app-questions/-/tree/q/pinia-presist/src 内提供的编译后文件进行替换,具体使用方式可以参考 demo,经过测试,对快手小程序平台有效。
// import piniaPersist from “pinia-plugin-persist-uni”;
import piniaPersist from “./pinia-persist-uni.es”; 如果有问题,请继续沟通。
补充:后续我联系作者修复了此问题,新版本的 presist 插件应该可以正常运行,你可以正常使用 npm 提供的 js 了


感谢回复,方法有效

感谢反馈,我来跟进这个问题。问题成功复现,是 presist 插件源码有问题,我提供一个兼容版本,现绕过此问题,后续尝试联系作者进行修复和更新

uni-app 中使用 Vue 3Pinia 时,如果你在快手小程序中遇到 Cannot read property 'getItem' of undefined 的错误,这通常是因为持久化插件(如 pinia-plugin-persistedstate)在尝试访问 localStoragesessionStorage,而快手小程序环境中并不支持这些 Web API。

解决方案

  1. 检查环境支持: 在快手小程序中,localStoragesessionStorage 是不可用的。你需要使用小程序提供的存储 API,如 wx.setStorageSyncwx.getStorageSync

  2. 自定义持久化存储: 你可以通过自定义持久化存储来适配快手小程序的环境。pinia-plugin-persistedstate 允许你自定义存储方式。

    首先,安装 pinia-plugin-persistedstate

    npm install pinia-plugin-persistedstate

    然后,在 main.jsmain.ts 中配置 Pinia 并使用自定义存储:

    import { createApp } from 'vue'
    import { createPinia } from 'pinia'
    import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
    import App from './App.vue'
    
    const pinia = createPinia()
    
    // 自定义存储适配器
    const customStorage = {
      getItem(key) {
        return wx.getStorageSync(key)
      },
      setItem(key, value) {
        wx.setStorageSync(key, value)
      },
      removeItem(key) {
        wx.removeStorageSync(key)
      }
    }
    
    pinia.use(piniaPluginPersistedstate({
      storage: customStorage
    }))
    
    const app = createApp(App)
    app.use(pinia)
    app.mount('#app')
  3. 处理异步存储: 如果小程序的存储 API 是异步的(如 wx.setStoragewx.getStorage),你需要确保在自定义存储适配器中正确处理异步操作。

    const customStorage = {
      async getItem(key) {
        return new Promise((resolve, reject) => {
          wx.getStorage({
            key,
            success(res) {
              resolve(res.data)
            },
            fail(err) {
              reject(err)
            }
          })
        })
      },
      async setItem(key, value) {
        return new Promise((resolve, reject) => {
          wx.setStorage({
            key,
            data: value,
            success() {
              resolve()
            },
            fail(err) {
              reject(err)
            }
          })
        })
      },
      async removeItem(key) {
        return new Promise((resolve, reject) => {
          wx.removeStorage({
            key,
            success() {
              resolve()
            },
            fail(err) {
              reject(err)
            }
          })
        })
      }
    }
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!