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

推荐订阅源

IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园_首页
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
ThreatConnect
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 聂微东
H
Help Net Security
T
Threat Research - Cisco Blogs
Blog — PlanetScale
Blog — PlanetScale
A
Arctic Wolf
G
Google Developers Blog
量子位
U
Unit 42
I
InfoQ
V
V2EX
F
Fox-IT International blog
P
Privacy & Cybersecurity Law Blog
V
Visual Studio Blog
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏
C
CERT Recently Published Vulnerability Notes
博客园 - 三生石上(FineUI控件)
T
The Exploit Database - CXSecurity.com
T
Tailwind CSS Blog
SecWiki News
SecWiki News
Know Your Adversary
Know Your Adversary
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
The Hacker News
The Hacker News
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
月光博客
月光博客
Recent Commits to openclaw:main
Recent Commits to openclaw:main
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
GRAHAM CLULEY
C
Cisco Blogs
I
Intezer
Simon Willison's Weblog
Simon Willison's Weblog
O
OpenAI News
Recorded Future
Recorded Future
T
Tenable Blog
W
WeLiveSecurity
腾讯CDC
Stack Overflow Blog
Stack Overflow Blog
T
The Blog of Author Tim Ferriss
www.infosecurity-magazine.com
www.infosecurity-magazine.com
D
Docker
C
Cybersecurity and Infrastructure Security Agency CISA
PCI Perspectives
PCI Perspectives

追梦人物的博客

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 自动生成接口文档 单元测试 限制接口访问频率 API 版本管理 - HelloDjango - django REST framework 教程 如何在 Windows 下搭建高效的 django 开发环境 拓展Python Markdown - 追梦人物的博客 加缓存为接口提速 基于 drf-haystack 实现文章搜索接口 评论接口 实现分类、标签、归档日期接口 在接口返回Markdown解析后的内容 文章详情接口 分页 使用视图集简化代码 用类视图实现首页 API 实现博客首页文章列表 API - HelloDjango - django REST framework 教程 初始化 RESTful API 风格的博客系统 django-rest-framework 是什么鬼? - HelloDjango - django REST framework 教程 结束 or 开始? Coverage.py 统计测试覆盖率 单元测试:测试评论应用 单元测试:测试 blog 应用 Django Haystack 全文检索与关键词高亮 Django 博客实现简单的全文搜索 开启 Django 博客的 RSS 功能 统计各个分类和标签下的文章数 稳定易用的 Django 分页库,完善分页功能 通过 Django Pagination 实现简单分页 在脚本中使用 ORM:Faker 批量生成测试数据 Django 官方推荐的姿势:类视图 Django 使用 union 合并不同模型(Model) 的查询集(QuerySet) 开发博客文章阅读量统计功能 使用 Docker 让部署 Django 项目更加轻松 使用 Certbot 向 Let's Encrypt 免费申请 HTTPS 证书 使用 Fabric 自动化部署 博客代码开源啦 (赠书)推荐一本django书籍:Django企业开发实战 Nginx+Gunicorn+Supervisor 部署 Django 博客应用 优化博客功能细节,提升使用体验 交流的桥梁:评论功能 分类、归档和标签页 页面侧边栏:使用自定义模板标签 自动生成文章摘要 - HelloDjango - Django博客教程(第二版) Markdown 文章自动生成目录,提升阅读体验 - HelloDjango - Django博客教程(第二版) 让博客支持 Markdown 语法和代码高亮 开发博客文章详情页 创作后台开启,请开始你的表演 博客从“裸奔”到“有皮肤” Django 的接客之道 Django 迁移、操作数据库 创建 Django 博客的数据库模型 开始进入 django 开发之旅 "空空如也"的博客应用 - HelloDjango - Django博客教程(第二版) 一种自顶而下的Python装饰器设计方法 Python提取支付宝和微信支付二维码 2018 - 我的学生生涯最后一年回顾 批量清除todo练习参考答案 筛选练习参考答案 删除todo练习参考答案 编辑todo练习参考答案 添加todo练习参考答案 标为完成练习参考答案 入门仪式_Hello_Vue练习参考答案 组件化todo应用 批量清除todo 本地存储 还剩多少todo未完成 全部标为完成 自定义指令实现自动聚焦 删除todo 编辑todo 添加todo 标为完成 UI 显示todo列表 入门仪式:Hello Vue 在学习django-rest-framework时收集的学习资料推荐 区块链理论与应用研究小组成员招募书 - 追梦人物的博客 Python界网红,豆瓣工程师董伟明加了我的QQ后 - 追梦人物的博客 招募Django学习小组项目组核心成员
筛选 - Vue 2.x Todo 教程
2019-01-10 · via 追梦人物的博客

接下来就是筛选功能,有了之前筛选全部未完成的 todo 的经验,相信实现其它的筛选思路也就非常清晰了,我们这里有三种筛选:

  • 全部:显示全部 todo
  • 进行中:显示未完成的 todo
  • 已完成:显示已完成的 todo

为了增强用户体验,选中的按钮应该高亮显示,我们这里把它标红了。

现在唯一的问题是,我们如何知道应该筛选出哪中类型的 todo 呢?用户是想要进行中的 todo 还是已完成的todo?可以发现用户会点击相应的按钮来表明他的意图。如果我们在用户点击按钮时把他的意图传递给 Vue 对象,Vue 就知道该怎么做了。

因此我们给 data 增加一个属性 intention,来记录用户的意图。我们定义三种意图:

  • all:想查看全部 todo
  • ongoing:想查看未完成的 todo
  • completed:想查看已完成的 todo
var app = new Vue({
        el: '#todo-app',
        data: function () {
            return {
                todos: [],
                newTodoTitle: '',
                editedTodo: null,
                intention: 'all', // 默认为 all
            }
        },
        ...
    })

然后我们需要根据用户的意图从 todos 中筛选 todo,之前说过,从 Vue 已绑定的数据中计算新的结果是计算属性的典型应用场景,所以我们加一个 filteredTodos 计算属性:

computed: {
            leftTodosCount: function () {
                return this.todos.filter(todo => !todo.finished).length
            },
            filteredTodos: function () {
                if (this.intention === 'ongoing') {
                    return this.todos.filter(todo => !todo.finished)
                } else if (this.intention === 'finished') {
                    return this.todos.filter(todo => todo.finished)
                } else {
                    // 其它未定义的意图我们为其返回全部 todos,
                    // 这里面已经包含了 all 意图了
                    return this.todos
                }
            },
        },

当然我们会发现未完成的 todo 分别在 filteredTodosleftTodosCount 两个计算属性中被计算了两次,为了优化一下计算效率,我们可以重构一下代码:

computed: {
            leftTodos: function () {
                return this.todos.filter(todo => !todo.finished)
            },
            leftTodosCount: function () {
                return this.leftTodos.length
            },
            filteredTodos: function () {
                if (this.flag === 'ongoing') {
                    return this.leftTodos
                } else if (this.flag === 'finished') {
                    return this.todos.filter(todo => todo.finished)
                } else {
                    // 其它未定义的意图我们为其返回全部 todos,
                    // 这里面已经包含了 all 意图了
                    return this.todos
                }
            }
        },

filteredTodos 就是我们根据用户意图返回的结果。

打开浏览器,刷新看看效果!发现怎么点击筛选按钮返回的还是全部 todo。好吧,我想你也想到了,我么只是在 vue 中定义了计算属性,但是用户点击按钮并没有把它们的意图传给 Vue 对象。我们来设置一下,让用户的意图在点击按钮时传给 Vue,这样 Vue 才知道如何操作。给各个筛选按钮绑定一个 click 事件。

<div>
    <span>剩余<span style="font-weight: bold;"> {{leftTodosCount}} </span>项未完成 ---</span>
    <span>筛选:
      <input type="button" value="全部"
             class="selected"
             @click="intention='all'"/>
      <input type="button" value="进行中"
             @click="intention='ongoing'"/>
      <input type="button" value="已完成"
             @click="intention='finished'"/>
      <input type="button" value="清除已完成">
      <input type="button" value="清除全部">
    </span>
  </div>

特别注意不要忘了 "intention='all'" all 两边的引号,因为这是一个字符串。

再次打开浏览器看效果,好吧,怎么点还是没反应。忘了刷新?刷新一下,还是没反应!哪里出错了?F12 打开控制台调试,Vue 显示欢迎消息没有任何错误提示!!

尝试着自己找找原因~~

我们之前在循环显示 todo 列表时使用的是 this.todos 的数据,当然你无论如何点击按钮循环的始终都是 todos 的数据。把循环的内容改为 filteredTodos

<li v-for='todo in filteredTodos' :key='todo.id'>
    <span :class="{finished: todo.finished}"
          @dblclick="editTodo(todo)">{{ todo.title }}</span>
    ...
</li>

大功告成!

练习

现在筛选的功能基本完成了,但是有一个地方还没有实现,用户点击相应意图的按钮,对应的按钮应该高亮显示,而现在始终只有全部按钮高亮,因为我们在 html 中为其设置了 class 始终为 selected。尝试修改代码实现需求。(hint:别忘了 Vue 的动态样式绑定。如何判断用户点击了哪个按钮呢?)

-- EOF --