You need to enable JavaScript to run this app. 如何使用Vue.js结合localStorage保存ToDo待办任务
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Vue.js结合localStorage保存ToDo待办任务

Vue版ToDo应用持久化到localStorage的正确实现

核心误区纠正

你之前直接存DOM元素innerHTML的思路,完全不适合Vue的开发模式:

  • localStorage要存储的是结构化的业务数据,而非页面渲染出来的HTML字符串
  • 存下来的HTML片段没有固定结构,后续根本没法从里面拆分出任务内容、完成状态、唯一标识这类核心信息,所有需要改任务状态、删任务、筛选任务的功能全都会失效

之前的错误写法:
localStorage.setItem('tasks', tasks.innerHTML)
这种写法相当于把页面上已经渲染好的HTML当数据源存了,完全颠倒了逻辑——Vue的核心是先有数据,再根据数据生成DOM,不是反过来把DOM存了当数据源。

具体实现步骤

  1. 定义结构化的响应式任务数据
    不要直接操作DOM拿内容,先把每个任务定义为带唯一标识、内容、状态的对象,整体存为响应式数组,单个任务的结构参考:

    {
      id: 任务唯一标识(可直接用时间戳生成),
      content: 任务文本内容,
      completed: 任务是否完成的布尔值
    }
    
  2. 初始化时从localStorage读取存量数据
    应用启动时先从本地缓存读取已存的任务,没有有效数据就给空数组作为初始值,同时加异常兜底,避免之前存的非法字符串(比如之前的innerHTML内容)导致解析报错:

    const getStoredTasks = () => {
      try {
        // 读取本地缓存的内容,解析成可操作的JSON结构
        return JSON.parse(localStorage.getItem('vue-todo-data')) || []
      } catch (err) {
        // 解析失败(比如缓存了之前的非JSON内容)就重置为空数组
        return []
      }
    }
    
  3. 数据变更时自动同步到localStorage
    用Vue的侦听器深度监听任务数组的变化,一旦任务增删改、状态切换,就把最新的任务数组序列化为JSON字符串存入本地缓存:

    • 一定要开启deep: true深度监听,不然单个任务内部的状态变更不会触发同步
    • localStorage只能存储字符串,对象数组需要用JSON.stringify()序列化后再存

完整可参考代码(Vue3 Composition API 写法)

<template>
  <div class="todo-app">
    <input v-model="newTaskContent" @keyup.enter="addTask" placeholder="输入新任务,按回车添加" />
    <ul>
      <li 
        v-for="task in tasks" 
        :key="task.id"
        :class="{ completed: task.completed }"
        @click="toggleTask(task.id)"
      >
        {{ task.content }}
        <button @click.stop="deleteTask(task.id)">删除</button>
      </li>
    </ul>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
// 新任务输入框的绑定值
const newTaskContent = ref('')
// 初始化任务数组:从本地缓存读取有效数据
const tasks = ref(getStoredTasks())

// 深度监听任务数组变化,自动写入本地缓存
watch(tasks, (latestTasks) => {
  localStorage.setItem('vue-todo-data', JSON.stringify(latestTasks))
}, { deep: true })

// 读取本地缓存的工具函数
function getStoredTasks() {
  try {
    return JSON.parse(localStorage.getItem('vue-todo-data')) || []
  } catch (err) {
    return []
  }
}

// 添加新任务
function addTask() {
  if(!newTaskContent.value.trim()) return
  tasks.value.push({
    id: Date.now(),
    content: newTaskContent.value.trim(),
    completed: false
  })
  newTaskContent.value = ''
}

// 切换任务完成状态
function toggleTask(taskId) {
  const targetTask = tasks.value.find(item => item.id === taskId)
  if(targetTask) targetTask.completed = !targetTask.completed
}

// 删除任务
function deleteTask(taskId) {
  tasks.value = tasks.value.filter(item => item.id !== taskId)
}
</script>

<style>
.completed {
  text-decoration: line-through;
  color: #999;
}
</style>

注意事项

  • 本地缓存的存储key不要和之前原生JS版本的key完全重名,避免之前存的innerHTML内容和现在的JSON结构冲突,导致解析报错
  • 如果是用Vue2 Options API实现,核心逻辑完全一致:在data中定义tasks数组(初始化时读本地缓存),在watch中侦听tasks的深层变化,同步写入缓存即可

内容的提问来源于stack exchange,提问作者user14945188

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.06 13:45:05