惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
云风的 BLOG
云风的 BLOG
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
Y
Y Combinator Blog
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Check Point Blog
M
MIT News - Artificial intelligence
Jina AI
Jina AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Apple Machine Learning Research
Apple Machine Learning Research
Hugging Face - Blog
Hugging Face - Blog
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
Stack Overflow Blog
Stack Overflow Blog
F
Fortinet All Blogs
博客园 - 司徒正美
I
InfoQ
Google DeepMind News
Google DeepMind News
GbyAI
GbyAI
U
Unit 42

追梦人物的博客

小度智能设备接入 Home Assistant,支持小爱同学语音控制 - 追梦人物的博客 0x05:Merkle Tree & Patricia Trie 0x04:ECDSA - 以太坊设计与实现 LeetCode 105 从前序与中序遍历构造二叉树 迭代算法原理 + 完整证明 0x03:Address - 以太坊设计与实现 0x02:Secp256k1 - 以太坊设计与实现 0x00:专栏开篇 - 以太坊设计与实现 0x01:RLP 编码 - 以太坊设计与实现 Bellman-Ford 算法原理及其在 DeFi 套利中的应用 - 追梦人物的博客 迪杰斯特拉(Dijkstra)最短路径算法原理、实现与证明 - 追梦人物的博客 实战:CEX-DEX 稳定币套利监控程序开发 - 追梦人物的博客 CEX-DEX 稳定币套利模型 - 追梦人物的博客 Uniswap 手续费和协议费机制剖析 - 追梦人物的博客 Uniswap 流动性机制及相关数学原理分析 - 追梦人物的博客 uv 替代 pyenv + pipx + poetry 环境管理实践 Rust 项目从创建到发布 - 追梦人物的博客 VS Code 调试 Python - 追梦人物的博客 比特币跨市场套利的数学模型 - 追梦人物的博客 ERC-20 相关知识点总结 - 追梦人物的博客 Django 老项目如何从 SQLite 迁到 PostgreSQL 自动生成接口文档 - HelloDjango - django REST framework 教程 单元测试 - HelloDjango - django REST framework 教程 限制接口访问频率 - HelloDjango - django REST framework 教程 API 版本管理 - HelloDjango - django REST framework 教程 如何在 Windows 下搭建高效的 django 开发环境 拓展Python Markdown - 追梦人物的博客 加缓存为接口提速 - HelloDjango - django REST framework 教程 基于 drf-haystack 实现文章搜索接口 - HelloDjango 评论接口 - HelloDjango - django REST framework 教程 实现分类、标签、归档日期接口 - HelloDjango - django REST framework 教程
删除todo练习参考答案 - Vue 2.x Todo 教程练习参考答案
2019-01-14 · via 追梦人物的博客

练习一

javascript 有一个 confirm 方法,调用该方法浏览器会弹出一个确认框,用户点击确认该方法会返回 true,点取消则不返回 true,因此用该方法可以实现我们的功能,只需修改 removeTodo 方法即可。

removeTodo: function (todo) {
    if (!confirm('确认删除?')) {
        return
    }
    this.todos.splice(this.todos.indexOf(todo), 1)
}

即如果用户没有点击确认,则 if 语句会执行,函数直接返回,不做删除操作。

练习二

这个功能的基本思路是,当用户删除某个 todo 后,我们用一个变量将这个删除的 todo 暂时保存下来,如果用户点击了撤销按钮,就把这个暂存的 todo 再插回原来的 todo 列表。为此,我们先给 vue 增加一个 removedTodo 变量,其初始值为 null:

data: function () {
    return {
        todos: [],
        newTodoTitle: '',
        removedTodo: null
    }
},

如果用户点击了删除 todo 按钮,就把这个删除的 todo 保存到 removedTodo 变量,修改一下 removeTodo 方法:

removeTodo: function (todo) {
    let pos = this.todos.indexOf(todo);
    this.removedTodo = {
        pos: pos,
        todo: this.todos.splice(pos, 1)[0]
    };
}

注意这里我们先获取了被删除的 todo 在 todo 列表的位置 pos,这个 pos 的作用是记录被删除 todo 的位置,撤销时我们就可以根据这个位置将被删除的 todo 插回原始位置。removedTodo 记录了位置信息和被删除的整个 todo。注意 this.todos.splice(pos, 1) 返回被删除的元素,即使只有一个元素,返回的也是数组,因此我们取索引 0 位置的元素。

让后我们给页面添加一个撤销按钮,该按钮监听点击事件并调用 restoreTodo 方法撤销删除操作:

methods: {
    ...
    restoreTodo: function () {
        let pos = this.removedTodo.pos;
        let restored = this.removedTodo.todo;
        this.todos.splice(pos, 0, restored);
        this.removedTodo = null;
    }
},

代码很好理解,注意这里 splice 方法第二个参数为 0 表示在数组的指定位置(pos)插入元素。撤销后别忘了将 removedTodo 重新置为 null。

然后加一个按钮,绑定 restoreTodo 的 click 事件:

<!-- todo list -->
<div v-if="hasRemovedTodo">
    <br>
    <input type="button" value="撤销" @click="restoreTodo()"/>
</div>
...
<!-- end todo list -->

要注意这里我们用 v-if 指令来条件渲染撤销按钮,因为只有当存在被删除的 todo 时,按钮才需要被渲染,如何判断是否存在被删除的 todo 呢,可以根据 removedTodo 是否为 null 来判断,是则没有,否则就有,为此我们创建一个计算属性 hasRemovedTodo 来指示是否存在被删除的 todo:

computed: {
    hasRemovedTodo: function () {
        return !!this.removedTodo
    }
}

撤销拓展

上面我们实现的撤销功能只记录了最近被删除的 todo,如果你连续删除多个 todo,只有最近被删除的 todo 能还原。为了支持多个 todo 还原,我们可以把 removedTodo 这个变量设置为一个栈,每删除一个 todo 就将被删除的 todo 压入栈中,点击撤销则弹出栈顶的 todo 还原,从而实现多步撤销功能。该功能不再实现,留给你作为拓展练习。

练习三

参见后面

-- EOF --