步骤:
- v-model为todo.title
- 用一个响应式变量editingTodoRef来记录当前编辑的是哪一个todo,用editingTodoRef和当前的todo判读是否相等来设置编辑状态。
- editTodo双击鼠标左键dblclick将当前的todo传递到editTodo并且将值赋给editingTodoRef。
- 失去焦点或者按下enter键来doneEdit完成修改.
- 按下esc键来取消编辑:在编辑前用一个变量originTitle来存储编辑前的值,cancelEdit取消编辑的时候将todo.title赋值为originTitle的值。
- 页面有一个功能:allDoneRef全部完成的时候下拉箭头的颜色为深色,因此,需要通过判断todo的completed属性全为true。
- setAllChecked设置为全部完成或者全部为不完成:如果页面传递过来的为true则为全完成,反之。
useEditTodo.js
import {
ref,computed
} from "vue"
export default function useEditTodo(todosRef) {
const editingTodoRef = ref(null); //当前正在修改哪一个todo
let originTitle = null; //缓存编辑之前的title值,用于取消编辑
// 鼠标左键双击
const editTodo = (todo) => {
originTitle = todo.title;
editingTodoRef.value = todo;;
}
// 完成编辑
const doneEdit = () => {
editingTodoRef.value = null;
}
// 取消编辑
const cancelEdit = (todo) => {
editingTodoRef.value = null;
todo.title = originTitle;
}
// 全部完成:已完成及为true页面的下拉箭头为深色
const allDoneRef = computed(() => {
const val = todosRef.value.filter((it) => !it.completed).length === 0;
return val;
})
// 全选完成或全选未完成.参数checked为true或者false
function setAllChecked(checked) {
todosRef.value.forEach((todo) => {
todo.completed = checked;
})
}
return {
editingTodoRef,
editTodo,
doneEdit,
cancelEdit,
allDoneRef,
setAllChecked
}
}
App.vue
<template>
<link rel="stylesheet" href="./style.css" />
<div id="app">
<section class="todoapp">
<header class="header">
<h1>todos</h1>
<input class="new-todo" autofocus="" autocomplete="off" placeholder="What needs to be done?" v-model="newTodoRef"
@keyup.enter="addTodo" />
</header>
<section class="main">
<input
id="toggle-all"
class="toggle-all"
type="checkbox"
:checked="allDoneRef"
@input="setAllChecked($event.target.checked)"
/>
<label for="toggle-all">Mark all as complete</label>
<ul class="todo-list">
<li
class="todo"
v-for="todo in filteredTodosRef"
:key="todo.id"
:class="{ completed: todo.completed,editing:todo === editingTodoRef }">
<div class="view">
<input class="toggle" type="checkbox" v-model="todo.completed" />
<!-- @dblclick鼠标左键双击事件 -->
<label @dblclick="editTodo(todo)">{{ todo.title }}</label>
<button class="destroy"></button>
</div>
<!-- 编辑状态 -->
<input
class="edit"
type="text"
v-model="todo.title"
@blur="doneEdit"
@keyup.enter="doneEdit"
@keyup.escape="cancelEdit(todo)"
/>
</li>
</ul>
</section>
<footer class="footer">
<span class="todo-count">
<strong>{{ remainingRef }}</strong>
<span>item{{ remainingRef === 1 ? '' : 's' }} left</span>
</span>
<ul class="filters">
<li><a href="#/all" :class="{ selected: visibilityRef === 'all' }">All</a></li>
<li><a href="#/active" :class="{ selected: visibilityRef === 'active' }">Active</a></li>
<li><a href="#/completed" :class="{ selected: visibilityRef === 'completed' }">Completed</a></li>
</ul>
<button class="clear-completed" v-show="completedRef">
Clear completed
</button>
</footer>
</section>
</div>
</template>
<script>
import useTodoList from "./composition/useTodoList"
import useNewTodo from "./composition/useNewTodo"
import useFilter from "./composition/useFilter";
import useEditTodo from "./composition/useEditTodo";
export default {
setup() {
const { todosRef } = useTodoList();
return {
todosRef,
...useNewTodo(todosRef),
...useFilter(todosRef),
...useEditTodo(todosRef)
}
}
}
</script>
该文章展示了如何在Vue.js应用中使用响应式变量和计算属性来管理待办事项的编辑状态。通过v-model、双击事件、键盘按键监听(Enter,Esc)来实现编辑和取消编辑功能。同时,利用计算属性检查所有待办事项是否全部完成,并提供了全选/全不选的实现方法。
697

被折叠的 条评论
为什么被折叠?



