尝试在更改的路由 vue 上记录到本地存储时,indexof() 始终返回 -1
Posted
技术标签:
【中文标题】尝试在更改的路由 vue 上记录到本地存储时,indexof() 始终返回 -1【英文标题】:indexof() returns -1 all the time when trying to record to local storage on changed route vue 【发布时间】:2018-09-14 04:16:54 【问题描述】:我试图在本地存储中记录页面 id,前提是它已经不存在。我创建了这个函数,但它不能正常工作,因为indexof()
总是返回-1
并且它多次记录相同的 id。
updateProgress (id)
let old = localStorage.getItem('visited').split(',')
if (old === null) old = ' '
if (old.indexOf(id) === -1)
let newProgress = [old, id]
localStorage.setItem('visited', newProgress.join(','))
Id 始终是一个字符串。
如果我这样做console.log(localStorage.getItem('visited'))
它会返回:
8,3,1,3,2,3,2,3,2,3,2,3,2,3,2,2,4,3,1,2,2,2,2,1,15,1,2,2,2,1
更新:我注意到,如果我刷新页面,它不会添加新值,但如果我将路由更改为另一个 id,它会再次添加它。总结一下,这可能是 vue.js 的问题,因为 id 是从路由中获取的,它是这样调用的:
created ()
this.updateProgress(this.id)
,
watch:
'$route' ()
this.updateProgress(this.id)
因此,当在 created()
中调用该函数时,它可以正常工作,但是当它在查找路线更改时被调用时,它就无法正常工作
更准确地说,如果我刷新 ID 为 4
的当前页面,然后 if 语句中的 console.log('updated', newProgress)
输出 null
和console.log(id, old)
在函数输出的末尾
4 (8) ["6", "5", "6", "3", "6", "3", "4", "2"]
如果我转到 ID 为 5 的页面,则会打印相同的控制台语句
updated (9) ["6", "5", "6", "3", "6", "3", "4", "2", 5]
代表新数组
和
5 (8) ["6", "5", "6", "3", "6", "3", "4", "2"]
表示旧数组。 5 已经在旧阵列中,但它也被添加到新阵列中。我不知道为什么会这样。
已解决 如果有人需要这个使用https://www.npmjs.com/package/vue-persistent-state 并且不要直接对本地存储做任何事情。我真的不知道这是与 vue 相关的问题。 我已经通过这种方式解决了这个问题:
import persistentState from 'vue-persistent-state'
let initialState =
progress: []
Vue.use(persistentState, initialState)
我的函数看起来像这样
updateProgress (id)
if (this.progress.indexOf(id.toString()) === -1)
this.progress.push(id.toString())
【问题讨论】:
什么是id
? old
是什么?你在比较字符串和整数吗?
id
的类型是什么?是string
还是number
?如果没有minimal reproducible example,这是无法回答的。你的意见是什么?
.split()
永远不会返回 null
。但是,如果项目不在本地存储中,.getItem()
将因此第一个语句将引发异常。
.split
返回一个数组而不是单个字符串,因此您需要遍历该数组。
@Žilvinas 请将您的代码更改为我们都可以自己复制和运行的代码。如果您不提供old
和id
的实际值,我们将无法真正帮助您。见minimal reproducible example。
【参考方案1】:
虽然代码有一些不可靠的地方,但它实际上应该可以正常工作。这是一个可运行的示例,其中包含用于演示目的的伪造 localStorage。
const fakeStorage = 'visited': null ;
const getItem = (key) => fakeStorage[key];
const setItem = (key, value) => fakeStorage[key] = value ;
const updateProgress = id =>
let old = (getItem('visited') || '').split(',');
if (old === null) old = ' ';
if (old.indexOf(id) === -1)
let newProgress = [old, id];
setItem('visited', newProgress.join(','));
console.log(getItem('visited'));
;
updateProgress('a');
updateProgress('a');
updateProgress('b');
updateProgress('a');
从一个空值开始,我唯一需要更改的是在拆分 (getItem('visited') || '').split(',')
之前将 getItem('visited')
包装为默认值 ''
,因为您不能在 null
上使用 split()
。
这样做,old === null
位是多余且不必要的(并且可能是有害的,因为它添加了一个额外的空白字符串。最好只删除该位,而是在拆分和初始化默认数组之前正确检查:
const fakeStorage = 'visited': null ;
const getItem = (key) => fakeStorage[key];
const setItem = (key, value) => fakeStorage[key] = value ;
const updateProgress = id =>
let old = getItem('visited');
old = (old && old.split(',')) || [];
if (old.indexOf(id) === -1)
const newProgress = [].concat(old, id);
setItem('visited', newProgress.join(','));
console.log(getItem('visited'));
;
updateProgress('a');
updateProgress('a');
updateProgress('b');
updateProgress('a');
您最好使用[].concat(old, id)
而不是奇数连接。虽然它在技术上有效,但它基本上是在做[[1,2,3], 4].join()
,这有点奇怪。
也就是说,您的代码应该可以按原样运行。如果不是,那么很可能不是代码问题,而是数据问题。
如果您的id
包含任何逗号,那是一件会彻底炸毁它的事情。同样,如果你不小心在里面放了一些不稳定的东西,那也可能把它炸毁。清除您的本地存储,然后重试。
在您的updateProgress()
末尾添加一个console.log()
,以输出id
、old
和newProgress
,以确保您有良好的数据输入。
【讨论】:
谢谢,这是非常详细且内容丰富的答案。我已经应用了您建议的更改。但是,我仍然无法让它正常工作,如果我刷新页面,那么它不会记录值,但是如果我更改路线然后返回相同的路线,它会再次记录它。这可能是某种 vue.js 问题 在updateProgress()
的末尾添加console.log(id, old)
并在if
语句中添加console.log('updated', newProgress)
。几次之后的输出是什么(用它们更新你的答案,这样你就可以很好地格式化它)。这可能有助于说明出了什么问题。
更新了答案,但不知道如何很好地格式化它。似乎值是正确的我不明白为什么它会这样工作,我可能不应该在 vue 项目中使用本地存储,因为我读到它的行为可能会有所不同。
我想我看到了你的问题。看起来您的 ID 实际上是一个整数,而不是一个字符串。在搜索之前尝试old.indexOf(id+"") === -1
将其转换为字符串。 =)以上是关于尝试在更改的路由 vue 上记录到本地存储时,indexof() 始终返回 -1的主要内容,如果未能解决你的问题,请参考以下文章