Nuxt js 中的 localStorage 在 SSR 模式下不工作

localStorage in Nuxt js is not working in SSR mode

我正在尝试使用 vuex 在购物车中添加商品,但在控制台中出现一些错误并且页面中的产品也没有显示。请告诉我如何解决这个问题。 这是控制台中的错误

client.js?06a0:103 SyntaxError: Unexpected token u in JSON at position 0
    at JSON.parse (<anonymous>)
    at Store.initializeStore (index.js?9101:14)
    at wrappedMutationHandler (vuex.esm.js?2f62:844)
    at commitIterator (vuex.esm.js?2f62:466)
    at Array.forEach (<anonymous>)
    at eval (vuex.esm.js?2f62:465)
    at Store._withCommit (vuex.esm.js?2f62:624)
    at Store.commit (vuex.esm.js?2f62:464)
    at Store.boundCommit [as commit] (vuex.esm.js?2f62:409)
    at VueComponent.mounted (default.vue?ec86:82)

这是我尝试使用 localStorage

的 store.js
export const state = () => ({
    cart:{
        items:[],
    },
    isAuthenticated: false,
    token: '',
    isLoading: false,

})
  
export const mutations = {
    initializeStore(state) {
        if (localStorage.getItem('cart')) {
          state.cart = JSON.parse(localStorage.getItem('cart'))
        } else {
          localStorage.setItem('cart', JSON.stringify(state.cart))
        }
    },
    addToCart(state, item) {
        const exists = state.cart.items.filter(i => i.product.id === item.product.id)
        if (exists.length) {
          exists[0].quantity = parseInt(exists[0].quantity) + parseInt(item.quantity)
        } else {
          state.cart.items.push(item)
        }
        localStorage.setItem('cart', JSON.stringify(state.cart))
    },

}

export const actions = {

}

这里是 default.vue 我试图从 vuex 访问 localStorage 的地方

export default {
  data(){
    return{
      title:'QL Gadgets',
      cart:{
        items:[]
      },
    }
  },
  mounted(){
    this.$store.commit('initializeStore')
  },
  computed:{
    cartTotalLenght(){
      let totalLenght = 0
      for(let i=0; i < this.cart.items.length; i++){
        totalLenght += this.cart.items[i].quantity
      }
      return totalLenght
    }
  },
  methods:{
    handleClick(){
        if(this.$refs.menu.classList.contains('hidden')){
            this.$refs.menu.classList.remove('hidden')
        }
        else{
            this.$refs.menu.classList.add('hidden')
        }
    }
  },
}

服务器无法查看浏览器本地存储,因为本地存储是客户端的一项功能。我认为正在发生的事情是 localStorage.getItem('cart') 返回未定义,而您看到的错误是在期望找到有效 JSON 时尝试 JSON.parse 未定义。

由于在服务器呈现期间您的模板中安装了挂钩,您的商店正在触发适用的服务器端功能。

您将需要等待在客户端调用 localStorage.getItem 然后将其传回服务器(如果在加载后需要额外的节点访问,则使用服务器中间件进行处理)或仅在客户端处理它-端并将结果提交到存储。

我还发现使用 vuex-persistedstate 是对这种逻辑或替代方案的一个很好的增强,您可以在第一次提交后有选择地保留您的购物车,然后您的服务器可以在您的应用程序的后续实例化中访问它。

这里的问题很可能是在某些时候您在本地存储中设置了一个不可 JSON 解析的字符串,或者响应中没有任何内容(undefinedu).使用您选择的浏览器(例如 Chrome or Firefox)检查您的本地存储是否属于这种情况。

无论如何,您应该处理从本地存储读取或解析结果的错误。例如,用户第一次访问该页面时,那里什么也没有,JSON.parse 将失败。例如:

export const mutations = {
  initializeStore(state) {
    try {
      state.cart = JSON.parse(localStorage.getItem('cart'))
    } catch {
      localStorage.setItem('cart', JSON.stringify(state.cart))
    }
  }
}