Vue 3 + Pinia 打造简易 Todo 应用,从 0 到 1 掌握状态管理

103 阅读2分钟

本文将手把手带你用 Vue 3 和 Pinia 构建一个简易的 Todo 应用,帮助你理解「响应式、组件化开发、状态管理」等核心知识。适合初学者快速上手 Vue 3 项目开发。


✅ 一、准备工作

我们使用 Vue CLI 创建项目:

bash
复制编辑
npm init vue@latest

在安装过程中选择:

  • ✅ Vue 3
  • ✅ Pinia
  • ✅ Vue Router(可选)

安装依赖:

bash
复制编辑
npm install
npm install pinia

main.js 中引入 Pinia:

js
复制编辑
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'

const app = createApp(App)
app.use(createPinia())
app.mount('#app')

📁 二、目录结构概览

css
复制编辑
src/
  components/
    TodoList.vue
    TodoInput.vue
  stores/
    todo.js
  App.vue
  main.js

📦 三、创建 Pinia Store:todo.js

js
复制编辑
import { defineStore } from 'pinia'

export const useTodoStore = defineStore('todo', {
  state: () => ({
    todos: [],
  }),
  actions: {
    addTodo(text) {
      this.todos.push({ text, done: false })
    },
    toggleTodo(index) {
      this.todos[index].done = !this.todos[index].done
    },
    deleteTodo(index) {
      this.todos.splice(index, 1)
    }
  }
})

🧩 四、构建 TodoInput 组件

vue
复制编辑
<template>
  <div>
    <input v-model="newTodo" @keyup.enter="add" placeholder="添加待办事项..." />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useTodoStore } from '../stores/todo'

const newTodo = ref('')
const store = useTodoStore()

function add() {
  if (newTodo.value.trim()) {
    store.addTodo(newTodo.value.trim())
    newTodo.value = ''
  }
}
</script>

📃 五、构建 TodoList 组件

vue
复制编辑
<template>
  <ul>
    <li v-for="(item, index) in todos" :key="index">
      <input type="checkbox" v-model="item.done" @change="toggle(index)" />
      <span :style="{ textDecoration: item.done ? 'line-through' : 'none' }">
        {{ item.text }}
      </span>
      <button @click="del(index)">删除</button>
    </li>
  </ul>
</template>

<script setup>
import { useTodoStore } from '../stores/todo'
import { storeToRefs } from 'pinia'

const store = useTodoStore()
const { todos } = storeToRefs(store)

const toggle = (i) => store.toggleTodo(i)
const del = (i) => store.deleteTodo(i)
</script>

🧱 六、App.vue 集成

vue
复制编辑
<template>
  <h1>📝 我的 Todo List</h1>
  <TodoInput />
  <TodoList />
</template>

<script setup>
import TodoInput from './components/TodoInput.vue'
import TodoList from './components/TodoList.vue'
</script>

🎉 七、运行项目体验效果

bash
复制编辑
npm run dev

效果:

  • 输入任务后按回车添加
  • 复选框切换完成状态
  • 点击按钮可删除任务

📦 八、Pinia 简要原理理解

  • defineStore 定义全局响应式状态
  • storeToRefs 用于将状态转换为响应式 ref
  • 可跨组件调用 store 实例,不需要 props 或 event bus

🚀 九、扩展思路(可继续深入)

  • 使用 LocalStorage 实现数据持久化
  • 加入任务分类(重要、普通)
  • 接入后端接口(如 JSONPlaceholder)
  • 加上 UI 框架(如 Element Plus、Naive UI)

✅ 总结

通过本文,你学会了:

  • 使用 Vue 3 + Pinia 构建小型项目
  • 响应式数据管理的最佳实践
  • 组件拆分 + 状态解耦的基本技巧

📌 发布到掘金的建议:

  • 标签建议添加:Vue3 前端开发 Pinia 状态管理
  • 推荐截图演示效果,增强可读性
  • 如果提供 GitHub 源码地址更佳(提升专业度)