当前位置: 首页 > article >正文

一个vue3的待办列表组件

一个vue3的待办列表组件, 仿企业微信的待办列表
TodoList.vue

<template>
    <div>
        <el-input v-model="todoInput" placeholder="写下你的待办事项..." class="el-input" @keyup.enter="addTodo"
            input-style="background-color: #EBECED;" />

        <el-table :data="todos" size="small" :show-header="false" @row-dblclick="editTodo">
            <el-table-column width="30">
                <template #default="scope">
                    <el-checkbox v-model="scope.row.completed" @change="toggleTodo(scope.row)">check</el-checkbox>
                </template>
            </el-table-column>
            <el-table-column prop="text" />
        </el-table>

        <div @click="showCompleted = !showCompleted" style="cursor: pointer; text-align: center; margin: 10px 0;">
            <el-divider v-if="!showCompleted">已完成 (点击展开)</el-divider>
            <el-divider v-else>已完成 (点击折叠)</el-divider>
        </div>

        <el-table :data="completedTodos" size="small" :show-header="false" v-if="showCompleted">
            <el-table-column width="30">
                <template #default="scope">
                    <el-checkbox v-model="scope.row.completed" @change="toggleTodo(scope.row)">check</el-checkbox>
                </template>
            </el-table-column>
            <el-table-column prop="text" />
        </el-table>

        <el-dialog title="修改" v-model="editDialogVisible">
            <el-form :model="editingTodo">
                <el-form-item label="内容">
                    <el-input ref="inputRef" v-model="editingTodo.text"></el-input>
                </el-form-item>
                <el-form-item label="状态">
                    <el-checkbox v-model="editingTodo.completed">已完成</el-checkbox>
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="editDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="confirmEdit()">确 定</el-button>
            </template>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
// 通用的待办列表
// 使用<TodoList :todoList="todoList" :save="save"></TodoList>
import { ref } from 'vue';

interface Todo {
    id: number;
    text: string;
    completed: boolean;
}

defineOptions({
    name: 'TodoList'
})

const props = defineProps({
    todoList: Array<Todo>,
    save: Function  //外部传入的保存方法,入参是Todo[]
});

const todoInput = ref('');
const todos = ref<Todo[]>([]);
const completedTodos = ref<Todo[]>([]);
const editDialogVisible = ref(false);
const editingTodo = ref({} as Todo);
const showCompleted = ref(false);
const inputRef = ref();

watch(() => props.todoList, (newValue) => {
    if (newValue) {
        newValue.sort((a, b) => b.id - a.id);
        todos.value = newValue.filter(t => !t.completed);
        completedTodos.value = newValue.filter(t => t.completed);
    }
})

const addTodo = () => {
    if (todoInput.value.trim() === '') return;
    todos.value.unshift({
        id: Date.now(),
        text: todoInput.value,
        completed: false
    });
    todoInput.value = '';
    saveTodoList();
};

const toggleTodo = async (todo: Todo) => {
    await new Promise(resolve => setTimeout(() => resolve("delay"), 300)); //产生一个点击后动画效果
    if (todo.completed) {
        if (!completedTodos.value.find(t => t.id == todo.id)) {
            completedTodos.value.unshift(todo);
        }
        todos.value = todos.value.filter(t => t.id !== todo.id);
    } else {
        if (!todos.value.find(t => t.id == todo.id)) {
            todo.id = Date.now();//更新时间到最新,所以每个todo其实是没有唯一值的
            todos.value.unshift(todo);
        }
        completedTodos.value = completedTodos.value.filter(t => t.id !== todo.id);
    }
    saveTodoList();
};

const editTodo = (todo: Todo) => {
    editingTodo.value = { ...todo };
    editDialogVisible.value = true;
    //组件focus的正确方式 setTimeout
    setTimeout(() => {
        inputRef.value?.focus();
    })
};

const confirmEdit = () => {
    editDialogVisible.value = false;
    var todo = todos.value.find(t => t.id == editingTodo.value.id)
    if (todo) {
        todo.text = editingTodo.value.text
        todo.completed = editingTodo.value.completed;
        toggleTodo(todo);
    }
};

const saveTodoList = () => {
    if (props.save) { // 添加空值检查
        props.save(todos.value.concat(completedTodos.value));
    }
}

</script>
<style scoped>
.el-input {
    --el-input-bg-color: #EBECED;
}
</style>

http://www.kler.cn/news/364497.html

相关文章:

  • Postgresql中和时间相关的字段类型及其适用场景
  • 使用 Python 和 Pandas 处理 Excel 数据:合并单元格示例
  • 15.6 JDBC数据库编程6——可滚动和可更新的ResultSet
  • 分账系统适用于那些商家?
  • Java8中Stream、Function、Opotions特性使用案例
  • 【Modern C++】特性学习与补漏
  • 【如何使用git将自己注释不上传到git服务器】
  • 博客搭建之路:hexo搜索引擎收录
  • pyflink 时序异常检测——PEWMA
  • 漏洞挖掘 | 记一次逻辑漏洞修改任意用户密码
  • 从0到1实现你自己的AI Chat应用
  • 密码学----RSA算法
  • Higress 云原生网关
  • JVM监控与调优工具
  • RabbitMQ最新版本4.0.2在Windows下的安装及使用
  • mac中按照官网教程安装了 pgsql 报错 command not found: psql
  • Java项目编译不通过,IDEA无法运行或调试Unit test类
  • 移动开发(四):.NET MAUI中Android应用修改安装图标和启动页面
  • EasyExcel_动态表头的导入导出
  • 非强化学习的对齐方法
  • 稳啦!掌握缓存一致性与失效预防措施——使用缓存不可或缺的指南!
  • MQL实验(二)作业
  • 【蓝桥杯选拔赛真题77】python计算小球 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析
  • [deadlock]死锁导致的设备登录无响应问题
  • 深入解析Java中的锁
  • 【业务】群组服务功能重构测试总结