尝试在更改的路由 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) 输出 nullconsole.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())
  

【问题讨论】:

什么是idold 是什么?你在比较字符串和整数吗? id类型是什么?是string 还是number?如果没有minimal reproducible example,这是无法回答的。你的意见是什么? .split() 永远不会返回 null。但是,如果项目不在本地存储中,.getItem() 将因此第一个语句将引发异常。 .split 返回一个数组而不是单个字符串,因此您需要遍历该数组。 @Žilvinas 请将您的代码更改为我们都可以自己复制和运行的代码。如果您不提供oldid 的实际值,我们将无法真正帮助您。见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(),以输出idoldnewProgress,以确保您有良好的数据输入。

【讨论】:

谢谢,这是非常详细且内容丰富的答案。我已经应用了您建议的更改。但是,我仍然无法让它正常工作,如果我刷新页面,那么它不会记录值,但是如果我更改路线然后返回相同的路线,它会再次记录它。这可能是某种 vue.js 问题 updateProgress() 的末尾添加console.log(id, old) 并在if 语句中添加console.log('updated', newProgress)。几次之后的输出是什么(用它们更新你的答案,这样你就可以很好地格式化它)。这可能有助于说明出了什么问题。 更新了答案,但不知道如何很好地格式化它。似乎值是正确的我不明白为什么它会这样工作,我可能不应该在 vue 项目中使用本地存储,因为我读到它的行为可能会有所不同。 我想我看到了你的问题。看起来您的 ID 实际上是一个整数,而不是一个字符串。在搜索之前尝试old.indexOf(id+"") === -1 将其转换为字符串。 =)

以上是关于尝试在更改的路由 vue 上记录到本地存储时,indexof() 始终返回 -1的主要内容,如果未能解决你的问题,请参考以下文章

在 Vue 中,我如何查看存储在其他设备本地存储中的数据

(Nuxt.js/Vue.js) - 脚本只运行一次,更改路由/刷新页面后停止运行

Vue路由器更改url但不更改内容

Vue路由器更改查询参数时防止滚动到顶部

如何在 vue 项目中预加载图片

未捕获的类型错误:无法使用“in”运算符在未定义的 vue 路由器中搜索“路径”