Vue3 学习教程,从入门到精通,vue3综合案例:“豪华版”待办事项(41)
vue3综合案例:“豪华版”待办事项
本文档将详细介绍使用 Vue CLI 搭建“豪华版”待办事项应用所涉及的语法知识点及其使用方法。每个知识点都将提供详细的解释和具体的代码案例,并包含详细的注释。最后,将展示一个综合性的案例,整合所有知识点。
1. 使用 Vue CLI 搭建项目
1.1 知识点:Vue CLI 安装与项目初始化
Vue CLI 是一个用于快速搭建 Vue.js 项目的脚手架工具。它提供了预设的配置和工具,帮助开发者快速启动项目。
安装 Vue CLI(如果尚未安装):
npm install -g @vue/cli
# 或者使用 yarn
yarn global add @vue/cli
初始化项目:
vue create luxury-todo-app
在交互式提示中选择需要的配置,例如 Babel、Vuex、Vue Router 等。
1.2 案例代码:项目结构
luxury-todo-app/
├── node_modules/
├── public/
│ └── index.html
├── src/
│ ├── assets/
│ ├── components/
│ │ ├── TaskItem.vue
│ │ └── EditTaskModal.vue
│ ├── store/
│ │ └── index.js
│ ├── views/
│ │ ├── Home.vue
│ │ └── Filters.vue
│ ├── App.vue
│ └── main.js
├── package.json
└── README.md
main.js - 入口文件:
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'createApp(App).use(store).mount('#app')
2. 页面结构和样式
2.1 知识点:Vue 单文件组件(SFC)
Vue 单文件组件(Single File Component, SFC)将模板、脚本和样式封装在一个文件中,便于维护和复用。
2.2 案例代码:App.vue
<!-- src/App.vue -->
<template><div id="app"><header><h1>豪华版待办事项</h1></header><main><Filters /><Home /></main></div>
</template><script>
import Filters from './components/Filters.vue'
import Home from './views/Home.vue'export default {name: 'App',components: {Filters,Home}
}
</script><style>
/* 基本样式 */
body {font-family: Arial, sans-serif;background-color: #f4f4f4;
}
header {background-color: #42b983;color: white;padding: 1em;text-align: center;
}
main {padding: 2em;
}
</style>
3. 添加待办事项页面
3.1 知识点:表单处理与事件绑定
使用 v-model
实现双向数据绑定,监听表单提交事件以添加新任务。
3.2 案例代码:Home.vue
<!-- src/views/Home.vue -->
<template><div><form @submit.prevent="addTask"><input v-model="newTask" placeholder="添加新任务" /><button type="submit">添加</button></form><ul><TaskItemv-for="task in filteredTasks":key="task.id":task="task"@toggle="toggleTask"@edit="editTask"@delete="deleteTask"/></ul></div>
</template><script>
import { mapState, mapGetters, mapActions } from 'vuex'
import TaskItem from '../components/TaskItem.vue'export default {name: 'Home',components: {TaskItem},data() {return {newTask: ''}},computed: {...mapState(['tasks']),...mapGetters(['filteredTasks'])},methods: {...mapActions(['addTaskAction', 'toggleTaskAction', 'deleteTaskAction', 'editTaskAction']),addTask() {if (this.newTask.trim()) {this.addTaskAction({ title: this.newTask, completed: false })this.newTask = ''}},toggleTask(id) {this.toggleTaskAction(id)},deleteTask(id) {this.deleteTaskAction(id)},editTask(task) {this.editTaskAction(task)}}
}
</script><style scoped>
form {display: flex;margin-bottom: 1em;
}
input {flex: 1;padding: 0.5em;font-size: 1em;
}
button {padding: 0.5em 1em;margin-left: 0.5em;font-size: 1em;background-color: #42b983;color: white;border: none;cursor: pointer;
}
button:hover {background-color: #369a6e;
}
ul {list-style: none;padding: 0;
}
</style>
4. 筛选项页面
4.1 知识点:动态筛选与计算属性
使用计算属性根据筛选条件过滤任务列表。
4.2 案例代码:Filters.vue
<!-- src/components/Filters.vue -->
<template><div><select v-model="selectedFilter"><option value="all">全部</option><option value="active">进行中</option><option value="completed">已完成</option></select></div>
</template><script>
import { mapMutations, mapState } from 'vuex'export default {name: 'Filters',data() {return {selectedFilter: 'all'}},computed: {...mapState(['filter']),...mapMutations(['setFilter'])},watch: {selectedFilter(newVal) {this.setFilter(newVal)}}
}
</script><style scoped>
select {padding: 0.5em;font-size: 1em;
}
</style>
5. 任务列表页面
5.1 知识点:列表渲染与组件复用
使用 v-for
指令渲染任务列表,并复用 TaskItem
组件。
5.2 案例代码:TaskItem.vue
<!-- src/components/TaskItem.vue -->
<template><li :class="{ completed: task.completed }"><input type="checkbox" v-model="task.completed" @change="toggle" /><span>{{ task.title }}</span><button @click="edit">编辑</button><button @click="remove">删除</button></li>
</template><script>
import { mapActions } from 'vuex'export default {name: 'TaskItem',props: {task: {type: Object,required: true}},methods: {...mapActions(['toggleTaskAction', 'deleteTaskAction', 'editTaskAction']),toggle() {this.toggleTaskAction(this.task.id)},remove() {this.deleteTaskAction(this.task.id)},edit() {this.editTaskAction(this.task)}}
}
</script><style scoped>
li {display: flex;align-items: center;padding: 0.5em;background-color: white;margin-bottom: 0.5em;border-radius: 4px;
}
li.completed span {text-decoration: line-through;color: #999;
}
input[type="checkbox"] {margin-right: 1em;
}
button {margin-left: 0.5em;padding: 0.3em 0.5em;background-color: #ff4d4d;color: white;border: none;border-radius: 4px;cursor: pointer;
}
button:hover {background-color: #ff1a1a;
}
</style>
6. 编辑任务弹框页面
6.1 知识点:模态框与表单编辑
使用 Vue 的条件渲染实现模态框,编辑任务内容。
6.2 案例代码:EditTaskModal.vue
<!-- src/components/EditTaskModal.vue -->
<template><div v-if="isVisible" class="modal"><div class="modal-content"><h2>编辑任务</h2><form @submit.prevent="save"><input v-model="task.title" placeholder="任务标题" /><button type="submit">保存</button><button type="button" @click="close">取消</button></form></div></div>
</template><script>
import { mapActions } from 'vuex'export default {name: 'EditTaskModal',props: {task: {type: Object,default: null}},data() {return {isVisible: false,taskData: {}}},methods: {...mapActions(['editTaskAction']),show(task) {this.isVisible = truethis.taskData = { ...task }},save() {this.editTaskAction(this.taskData)this.close()},close() {this.isVisible = falsethis.taskData = {}}}
}
</script><style scoped>
.modal {position: fixed;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.5);display: flex;justify-content: center;align-items: center;
}
.modal-content {background-color: white;padding: 2em;border-radius: 8px;width: 300px;
}
form {display: flex;flex-direction: column;
}
input {padding: 0.5em;font-size: 1em;margin-bottom: 1em;
}
button {padding: 0.5em;margin: 0.5em 0;font-size: 1em;
}
button[type="submit"] {background-color: #42b983;color: white;border: none;cursor: pointer;
}
button[type="submit"]:hover {background-color: #369a6e;
}
button[type="button"] {background-color: #ff4d4d;color: white;border: none;cursor: pointer;
}
button[type="button"]:hover {background-color: #ff1a1a;
}
</style>
7. Vuex 管理任务列表
7.1 知识点:Vuex 状态管理
使用 Vuex 管理应用状态,包括任务列表和筛选条件。
7.2 案例代码:store/index.js
// src/store/index.js
import { createStore } from 'vuex'export default createStore({state: {tasks: [],filter: 'all'},mutations: {ADD_TASK(state, task) {state.tasks.push(task)},TOGGLE_TASK(state, id) {const task = state.tasks.find(t => t.id === id)task.completed = !task.completed},DELETE_TASK(state, id) {state.tasks = state.tasks.filter(t => t.id !== id)},EDIT_TASK(state, task) {const index = state.tasks.findIndex(t => t.id === task.id)state.tasks[index] = task},SET_FILTER(state, filter) {state.filter = filter}},actions: {addTaskAction({ commit }, task) {const newTask = {id: Date.now(),title: task.title,completed: task.completed}commit('ADD_TASK', newTask)},toggleTaskAction({ commit }, id) {commit('TOGGLE_TASK', id)},deleteTaskAction({ commit }, id) {commit('DELETE_TASK', id)},editTaskAction({ commit }, task) {commit('EDIT_TASK', task)},setFilter({ commit }, filter) {commit('SET_FILTER', filter)}},getters: {filteredTasks(state) {if (state.filter === 'active') {return state.tasks.filter(t => !t.completed)} else if (state.filter === 'completed') {return state.tasks.filter(t => t.completed)}return state.tasks}}
})
8. 持久化任务
8.1 知识点:本地存储与生命周期钩子
使用浏览器的本地存储(localStorage)实现任务的持久化。
8.2 案例代码:store/index.js(续)
// src/store/index.js(续)
import { createStore } from 'vuex'export default createStore({state: {tasks: JSON.parse(localStorage.getItem('tasks')) || [],filter: 'all'},mutations: {// ...前面的 mutationsADD_TASK(state, task) {state.tasks.push(task)localStorage.setItem('tasks', JSON.stringify(state.tasks))},TOGGLE_TASK(state, id) {const task = state.tasks.find(t => t.id === id)task.completed = !task.completedlocalStorage.setItem('tasks', JSON.stringify(state.tasks))},DELETE_TASK(state, id) {state.tasks = state.tasks.filter(t => t.id !== id)localStorage.setItem('tasks', JSON.stringify(state.tasks))},EDIT_TASK(state, task) {const index = state.tasks.findIndex(t => t.id === task.id)state.tasks[index] = tasklocalStorage.setItem('tasks', JSON.stringify(state.tasks))},SET_FILTER(state, filter) {state.filter = filter}},actions: {// ...前面的 actionsaddTaskAction({ commit }, task) {const newTask = {id: Date.now(),title: task.title,completed: task.completed}commit('ADD_TASK', newTask)},// 其他 actions 不需要修改},getters: {// ...前面的 getters}
})
9. 综合案例
9.1 整合所有组件与功能
以下是一个整合所有组件和功能的完整示例:
<!-- src/views/Home.vue -->
<template><div><form @submit.prevent="addTask"><input v-model="newTask" placeholder="添加新任务" /><button type="submit">添加</button></form><Filters /><ul><TaskItemv-for="task in filteredTasks":key="task.id":task="task"@toggle="toggleTask"@edit="editTask"@delete="deleteTask"/></ul><EditTaskModal :task="editingTask" /></div>
</template><script>
import { mapState, mapGetters, mapActions } from 'vuex'
import Filters from '../components/Filters.vue'
import TaskItem from '../components/TaskItem.vue'
import EditTaskModal from '../components/EditTaskModal.vue'export default {name: 'Home',components: {Filters,TaskItem,EditTaskModal},data() {return {newTask: '',editingTask: null}},computed: {...mapState(['tasks', 'filter']),...mapGetters(['filteredTasks'])},methods: {...mapActions(['addTaskAction', 'toggleTaskAction', 'deleteTaskAction', 'editTaskAction']),addTask() {if (this.newTask.trim()) {this.addTaskAction({ title: this.newTask, completed: false })this.newTask = ''}},toggleTask(id) {this.toggleTaskAction(id)},deleteTask(id) {this.deleteTaskAction(id)},editTask(task) {this.editingTask = task}},watch: {editingTask(newVal) {if (newVal) {this.$refs.editModal.show(newVal)}}}
}
</script><style scoped>
form {display: flex;margin-bottom: 1em;
}
input {flex: 1;padding: 0.5em;font-size: 1em;
}
button {padding: 0.5em 1em;margin-left: 0.5em;font-size: 1em;background-color: #42b983;color: white;border: none;cursor: pointer;
}
button:hover {background-color: #369a6e;
}
ul {list-style: none;padding: 0;
}
</style>
9.2 运行项目
确保所有组件和 Vuex store 已正确配置后,运行以下命令启动项目:
npm run serve
打开浏览器访问 http://localhost:8080
,即可看到豪华版待办事项应用。
10. 小结
本文档详细介绍了使用 Vue CLI 搭建“豪华版”待办事项应用的关键知识点及其实现方法。通过组件化、Vuex 状态管理、模态框编辑和本地存储等技术的应用,实现了功能丰富且用户友好的待办事项应用。希望通过这些具体的案例代码和详细注释,能够帮助开发者更好地理解和应用 Vue.js 进行项目开发。