Vue怎么制作Todo List网页

发布时间:2022-05-05 17:19:39 作者:iii
来源:亿速云 阅读:149
# Vue怎么制作Todo List网页

## 前言

在现代前端开发中,Vue.js因其简洁的API和响应式数据绑定特性,成为构建交互式Web应用的热门选择。本文将详细介绍如何使用Vue.js构建一个功能完整的Todo List应用,涵盖从环境搭建到高级功能的完整实现流程。

## 一、项目初始化

### 1.1 环境准备
首先确保已安装Node.js(建议版本16+)和npm/yarn包管理器。

```bash
node -v
npm -v

1.2 创建Vue项目

使用Vue CLI创建新项目:

npm install -g @vue/cli
vue create vue-todo-list
cd vue-todo-list
npm run serve

1.3 项目结构说明

public/          # 静态资源
src/
  ├── assets/     # 静态资源
  ├── components/ # 组件
  ├── App.vue     # 根组件
  └── main.js     # 入口文件

二、基础功能实现

2.1 创建Todo组件

新建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>

2.2 在App.vue中引入组件

<template>
  <div id="app">
    <TodoList />
  </div>
</template>

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

export default {
  components: {
    TodoList
  }
}
</script>

三、功能扩展

3.1 添加完成状态

修改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>

3.2 删除功能

添加删除按钮和方法:

<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>

四、状态管理

4.1 使用Vuex管理状态

安装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
  }
})

4.2 修改组件使用Vuex

<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>

五、持久化存储

5.1 使用localStorage

修改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
  }
})

六、高级功能实现

6.1 筛选功能

添加筛选功能:

<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>

6.2 编辑功能

实现双击编辑:

<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>

七、样式优化

7.1 添加CSS动画

/* 添加过渡效果 */
.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;
}

八、部署上线

8.1 构建生产版本

npm run build

8.2 部署到GitHub Pages

  1. 安装gh-pages:
npm install gh-pages --save-dev
  1. 在package.json中添加:
"scripts": {
  "deploy": "gh-pages -d dist"
}
  1. 执行部署:
npm run build
npm run deploy

九、总结

通过本文,我们完整实现了一个具有以下功能的Todo List应用: - 添加/删除任务 - 标记完成状态 - 本地持久化存储 - 任务筛选功能 - 任务编辑功能 - 动画过渡效果

这个项目涵盖了Vue的核心概念: - 组件化开发 - 响应式数据绑定 - 计算属性 - 条件渲染 - 列表渲染 - 事件处理 - Vuex状态管理 - 自定义指令

十、进一步学习建议

  1. 添加用户认证功能
  2. 实现后端API连接
  3. 添加标签分类功能
  4. 实现拖拽排序
  5. 添加截止日期提醒
  6. 开发移动端应用

完整的项目代码可以访问GitHub仓库:vue-todo-list-demo

希望本文能帮助你掌握Vue.js的核心概念和开发流程,为构建更复杂的应用打下坚实基础。 “`

推荐阅读:
  1. TODO:Google Analytics简单使用
  2. iOS——TODO LIST

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue

上一篇:Vue.js+cube-ui怎么实现类似头条效果的横向滚动导航条

下一篇:Vue怎么用Axios异步请求API

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》