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

推荐订阅源

Schneier on Security
Schneier on Security
T
The Blog of Author Tim Ferriss
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
I
InfoQ
罗磊的独立博客
小众软件
小众软件
H
Help Net Security
Vercel News
Vercel News
M
MIT News - Artificial intelligence
雷峰网
雷峰网
Stack Overflow Blog
Stack Overflow Blog
D
Docker
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Heimdal Security Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
W
WeLiveSecurity
Google DeepMind News
Google DeepMind News
B
Blog
Forbes - Security
Forbes - Security
T
Troy Hunt's Blog
月光博客
月光博客
The Cloudflare Blog
Last Week in AI
Last Week in AI
J
Java Code Geeks
Jina AI
Jina AI
TaoSecurity Blog
TaoSecurity Blog
Google Online Security Blog
Google Online Security Blog
C
Check Point Blog
PCI Perspectives
PCI Perspectives
SecWiki News
SecWiki News
P
Proofpoint News Feed
Attack and Defense Labs
Attack and Defense Labs
Cisco Talos Blog
Cisco Talos Blog
V
Visual Studio Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The Last Watchdog
The Last Watchdog
F
Full Disclosure
T
Threatpost
NISL@THU
NISL@THU
量子位
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Fortinet All Blogs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hugging Face - Blog
Hugging Face - Blog
有赞技术团队
有赞技术团队

追梦人物的博客

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

Vue 的组件是一个可复用的 Vue 实例,组件可以有自己的数据(data),组件可以互相嵌套而形成一个树状组织结构。因为组件也是一个 Vue 的实例,因此它的创建和我们之前使用 new Vue 创建 Vue 实例非常类似。

Vue 引入组件的目的,就是为了复用。例如一个按钮,把和这个按钮相关的数据和操作逻辑封装到一个组件里,那么在需要的地方,引入这个组件就可以生成一个按钮,提高了代码的复用性。

Vue 组件,主要需要了解的是父组件如何向子组件传递数据,以及子组件如何向父组件发送消息。现在不理解没有关系,下面的教程会使用 todo 应用来向你演示这两个机制,以及我们如何在 Vue 中使用它。

为了简单起见,我们只演示将 todo 项组件化,这个例子已经足以说明 Vue 组件的使用方法了,整个应用的组件化将作为练习,由你自己利用教程中所学的的知识完成,具体来说,我们把这个看成一个组件:

<li v-for='todo in filteredTodos' :key='todo.id'>
  <span :class="{completed: todo.completed}"
        @dblclick="editTodo(todo)">{{ todo.title }}</span>
  <input type="button"
         value="标为完成"
         @click="markAsCompleted(todo)"/>
  <input v-if="todo.removed" type="button" value="还原" @click="restoreTodo(todo)"/>
  <input v-else="todo.removed" type="button" value="删除" @click="removeTodo(todo)"/>
  <input type="text"
         value="编辑 todo..."
         v-focus="true"
         v-if="editedTodo!==null && editedTodo.id===todo.id"
         v-model="todo.title"
         @keyup.enter="editDone(todo)"
         @keyup.esc="cancelEdit(todo)"/>
</li>

Vue 需要一个模板来渲染组件,上面就是要渲染的模板,我们把模板写在一个类型为 text/x-template 的 script 标签里:

<script type="text/x-template" id="todo-item">
  <li>
    <span :class="{completed: todo.completed}"
          @dblclick="editTodo(todo)">{{ todo.title }}</span>
    <input type="button"
           value="标为完成"
           @click="markAsCompleted(todo)"/>
    <input type="button" value="删除" @click="removeTodo(todo)"/>
    <input type="text"
           value="编辑 todo..."
           v-focus="true"
           v-if="editedTodo!==null && editedTodo.id===todo.id"
           v-model="todo.title"
           @keyup.enter="editDone(todo)"
           @keyup.esc="cancelEdit(todo)"/>
  </li>
</script>

要注意模板和上面一段 html 代码的不同,去掉了 li 标签上的 v-for 和绑定指令,因为我们这只是在定义组件,而不是像上面那样循环渲染组件。还要注意 script 标签设置了 id="todo-item",这将告诉 Vue 在注册组件时,如何定位渲染的模板所在位置。

然后我们在 Vue 中注册我们自定义的组件,使用 Vue.component 方法,第一个参数是你给这个组件起的组件名,第二个参数是一个对象,和我们 new Vue 示例时的选项非常类似:

Vue.component('todo-item', {
    template: '#todo-item',
    data: function () {
        return {
            editedTodo: null // 用户暂存编辑前的 todo 状态
        }
    },
    props: {
        todo: {
            type: Object,
            required: true,
        },
    },
    methods: {
        ...
    },
    directives: {
        focus: {
            inserted: function (el) {
                el.focus()
            }
        }
    }
});

data 中只有一个 editedTodo,在编辑功能中会用到,其用法和之前是一样的,只是从 Vue 实例移到了组件中。props 是一个新的对象,用来接收组件需要使用到的数据。试想,我们的 todo-item 组件需要一个 todo 模型的数据,才能渲染成一个待办事项,但这个数据从哪里来呢?答案就是通过这个 props 传递。当某个值传给 props 的时候,他就变成了组件实例的一个属性。比如这里 props 它接收一个 todo,那么当一个 todo 传给组件时,组件就多了一个 todo 属性,我们可以在组件中通过 this.todo 引用。同时,我们还设置了 todo 数据的要求,即它的类型是一个 Object,而且必须传递,不能缺省。

那么这个组件有哪些方法呢?以下方法是和这个组件相关的,我们从 app 这个 Vue 实例里复制过来:

methods: {
    markAsCompleted: function (todo) {
        todo.completed = true
    },
    removeTodo: function (todo) {
        this.todos.splice(this.todos.indexOf(todo), 1)
    },
    editTodo: function (todo) {
        this.editedTodo = {id: todo.id, title: todo.title}
    },
    editDone: function (todo) {
        this.editedTodo = null
    },
    cancelEdit: function (todo) {
        todo.title = this.editedTodo.title;
        this.editedTodo = null
    }
},

和单个待办事项操作相关的方法我们都复制了过来,仔细观察可以发现,除了 removeTodo 这个方法外,其它方法均只涉及从 props 传递过来的 todo,而 removeTodo 这个操作则涉及到从 app 这个 Vue 实例的 data 中 todos 数组中删除数据。这里就出现了问题,组件是封闭,它无法直接访问父组件的数据,而且组件的数据流向是单向的,只能从父组件通过 props 传到子组件,那么如何使组件中的操作反应到父组件上呢?

我们可以通过事件向父级组件发送消息,我们可以使用如下的方法发送一个事件消息:

removeTodo: function (todo) {
    this.$emit('remove-todo', todo)
},

第一个是你给这个事件取得名字,同时时间还可以携带数据,这里我们把组件实例绑定的 todo 也发送了出去。

定义了这个组件,我们就可以在应用中使用了,将原来渲染待办事项的 html 代码替换为自定义的组件:

<!-- todo list -->
<ul>
  <todo-item v-for="todo in filteredTodos"
             :todo="todo"
             :key="todo.id"
             @remove-todo="removeTodo"/>
</ul>
<!-- end todo list -->

和之前的 li 元素是类似的,只是这里换成了我们自定义的组件,Vue 最终还是把 todo-item 渲染成 li 元素,因为这个组件使用的模板就是那个 li 元素。

和 @click 一样,我们这里绑定监听了一个 remove-todo 事件,这个事件组件中点击删除按钮触发的,一旦监听到这个事件被触发,就会调用 app 这个 Vue 实例中的 removeTodo 方法(注意不是组件 todo-item 中的 removeTodo 方法),因为只有在 app 这个 Vue 实例中才能访问到 todos 数组:

var app = new Vue({
    el: '#todo-app',
    data: function () {
        return {
            todos: todoStorage.fetch(),
            newTodoTitle: '',
            intention: 'all', // 默认为 all
        }
    },
    ...
    methods: {
        ...
        removeTodo: function (todo) {
            this.todos.splice(this.todos.indexOf(todo), 1)
        },
    },
})

要注意 app 这个实例中 data 对象有一个 editedTodo 属性,这个属性移到了组件中,所以被删除了,同时所有移到组件中的方法也删除了。

同样的,在组件中也可以定义计算属性,举个例子,为了决定编辑框是否显示,我们使用了如下的判断表达式:

v-if="editedTodo!==null && editedTodo.id===todo.id"

我们可以把这个表达式定义成组件中的一个计算属性:

computed: {
    editing: function () {
        return this.editedTodo !== null && this.editedTodo.id === this.todo.id
    }
},

让后在组件模板中引用它:

<input type="text"
       value="编辑 todo..."
       v-focus="true"
       v-if="editing"
       v-model="todo.title"
       @keyup.enter="editDone(todo)"
       @keyup.esc="cancelEdit(todo)"/>

至此,我们应用的组件化示例就完成了。

尽管这是一个刻意设计的例子,组件的划分也不一定合理,但通过这个例子很好地演示了父组件到子组件的数据传递方式以及子组件通过事件向父组件传递消息的方式。把这两点牢记在心,然后把整个应用都组件化吧!这个任务就交给你了,把之前学到的东西都用起来,另外 Vue 的官方文档更是你遇到问题时最为权威的参考资料,不要忘了它!

教程至此全部结束,请期待后续 Vue HackerNews 项目的教程,以及 webpack 前端工程化的实践教程,感谢阅读!

-- EOF --