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 解析的字符串,或者响应中没有任何内容(undefined
以 u
).使用您选择的浏览器(例如 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))
}
}
}
我正在尝试使用 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.jsexport 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 解析的字符串,或者响应中没有任何内容(undefined
以 u
).使用您选择的浏览器(例如 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))
}
}
}