您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Vue怎么制作Todo List网页
## 前言
在现代前端开发中,Vue.js因其简洁的API和响应式数据绑定特性,成为构建交互式Web应用的热门选择。本文将详细介绍如何使用Vue.js构建一个功能完整的Todo List应用,涵盖从环境搭建到高级功能的完整实现流程。
## 一、项目初始化
### 1.1 环境准备
首先确保已安装Node.js(建议版本16+)和npm/yarn包管理器。
```bash
node -v
npm -v
使用Vue CLI创建新项目:
npm install -g @vue/cli
vue create vue-todo-list
cd vue-todo-list
npm run serve
public/ # 静态资源
src/
├── assets/ # 静态资源
├── components/ # 组件
├── App.vue # 根组件
└── main.js # 入口文件
新建src/components/TodoList.vue
文件:
<template>
<div class="todo-container">
<h1>Todo List</h1>
<input
v-model="newTodo"
@keyup.enter="addTodo"
placeholder="Add new todo..."
/>
<ul>
<li v-for="(todo, index) in todos" :key="index">
{{ todo.text }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
newTodo: '',
todos: []
}
},
methods: {
addTodo() {
if (this.newTodo.trim()) {
this.todos.push({
text: this.newTodo,
completed: false
})
this.newTodo = ''
}
}
}
}
</script>
<style scoped>
.todo-container {
max-width: 500px;
margin: 0 auto;
padding: 20px;
}
input {
width: 100%;
padding: 10px;
margin-bottom: 20px;
}
</style>
<template>
<div id="app">
<TodoList />
</div>
</template>
<script>
import TodoList from './components/TodoList.vue'
export default {
components: {
TodoList
}
}
</script>
修改TodoList.vue:
<li
v-for="(todo, index) in todos"
:key="index"
:class="{ completed: todo.completed }"
@click="toggleTodo(index)"
>
{{ todo.text }}
</li>
<script>
methods: {
toggleTodo(index) {
this.todos[index].completed = !this.todos[index].completed
}
}
</script>
<style>
.completed {
text-decoration: line-through;
color: #ccc;
}
</style>
添加删除按钮和方法:
<li v-for="(todo, index) in todos" :key="index">
<span
:class="{ completed: todo.completed }"
@click="toggleTodo(index)"
>
{{ todo.text }}
</span>
<button @click="removeTodo(index)">×</button>
</li>
<script>
methods: {
removeTodo(index) {
this.todos.splice(index, 1)
}
}
</script>
安装Vuex:
npm install vuex
创建src/store/index.js
:
import { createStore } from 'vuex'
export default createStore({
state: {
todos: []
},
mutations: {
ADD_TODO(state, todo) {
state.todos.push(todo)
},
TOGGLE_TODO(state, index) {
state.todos[index].completed = !state.todos[index].completed
},
REMOVE_TODO(state, index) {
state.todos.splice(index, 1)
}
},
actions: {
addTodo({ commit }, todo) {
commit('ADD_TODO', todo)
},
toggleTodo({ commit }, index) {
commit('TOGGLE_TODO', index)
},
removeTodo({ commit }, index) {
commit('REMOVE_TODO', index)
}
},
getters: {
allTodos: state => state.todos
}
})
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapGetters(['allTodos'])
},
methods: {
...mapActions(['addTodo', 'toggleTodo', 'removeTodo']),
handleAddTodo() {
if (this.newTodo.trim()) {
this.addTodo({
text: this.newTodo,
completed: false
})
this.newTodo = ''
}
}
}
}
</script>
修改store/index.js:
export default createStore({
state: {
todos: JSON.parse(localStorage.getItem('todos')) || []
},
mutations: {
// ...原有mutations
SAVE_TODOS(state) {
localStorage.setItem('todos', JSON.stringify(state.todos))
}
},
actions: {
addTodo({ commit }, todo) {
commit('ADD_TODO', todo)
commit('SAVE_TODOS')
},
// 其他actions也添加SAVE_TODOS
}
})
添加筛选功能:
<template>
<div>
<div class="filters">
<button
v-for="filter in filters"
:key="filter"
@click="currentFilter = filter"
:class="{ active: currentFilter === filter }"
>
{{ filter }}
</button>
</div>
<ul>
<li v-for="(todo, index) in filteredTodos" :key="index">
<!-- 原有内容 -->
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
filters: ['all', 'active', 'completed'],
currentFilter: 'all'
}
},
computed: {
filteredTodos() {
switch(this.currentFilter) {
case 'active':
return this.allTodos.filter(todo => !todo.completed)
case 'completed':
return this.allTodos.filter(todo => todo.completed)
default:
return this.allTodos
}
}
}
}
</script>
实现双击编辑:
<template>
<li v-for="(todo, index) in filteredTodos" :key="index">
<div v-if="todo !== editingTodo">
<span @dblclick="startEditing(todo)">{{ todo.text }}</span>
</div>
<input
v-else
v-model="editingText"
@blur="finishEditing(todo)"
@keyup.enter="finishEditing(todo)"
@keyup.esc="cancelEditing"
v-focus
>
</li>
</template>
<script>
export default {
data() {
return {
editingTodo: null,
editingText: ''
}
},
methods: {
startEditing(todo) {
this.editingTodo = todo
this.editingText = todo.text
},
finishEditing(todo) {
if (this.editingText.trim()) {
this.$store.dispatch('editTodo', {
index: this.allTodos.indexOf(todo),
text: this.editingText
})
}
this.cancelEditing()
},
cancelEditing() {
this.editingTodo = null
this.editingText = ''
}
},
directives: {
focus: {
inserted(el) {
el.focus()
}
}
}
}
</script>
/* 添加过渡效果 */
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* 按钮样式 */
button {
background: none;
border: none;
color: #ff5a5f;
cursor: pointer;
font-size: 1.2em;
margin-left: 10px;
}
button:hover {
color: #ff2d2d;
}
/* 筛选按钮 */
.filters button {
margin: 0 5px;
padding: 5px 10px;
border: 1px solid #ddd;
background: white;
}
.filters button.active {
border-color: #42b983;
color: #42b983;
}
npm run build
npm install gh-pages --save-dev
"scripts": {
"deploy": "gh-pages -d dist"
}
npm run build
npm run deploy
通过本文,我们完整实现了一个具有以下功能的Todo List应用: - 添加/删除任务 - 标记完成状态 - 本地持久化存储 - 任务筛选功能 - 任务编辑功能 - 动画过渡效果
这个项目涵盖了Vue的核心概念: - 组件化开发 - 响应式数据绑定 - 计算属性 - 条件渲染 - 列表渲染 - 事件处理 - Vuex状态管理 - 自定义指令
完整的项目代码可以访问GitHub仓库:vue-todo-list-demo
希望本文能帮助你掌握Vue.js的核心概念和开发流程,为构建更复杂的应用打下坚实基础。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。