如何实现一个稍微复杂的simplelist

使用过一些清单类的应用程序,像 WunderList, Google Keep等,用来记录一些计划和安排,也试着将自己的计划安排同笔记一起整理在 Evernote 中,但是无论哪种方式用起来总觉得少了点什么,如果两者的一些功能能够结合起来,就很完美了。

“todo”和“note”之间的关系本来就很微妙,一个“todo”写得详细点不就成了“note”吗?于是自己写了一个稍微复杂一点的清单程序,今天将项目总结整理在此。

我试着将 todo和 note 结合,可以像 WunderList 一样记录计划,又可以 Evernote
一样管理笔记。在开发过程中,反复调整和修改,最终发现:其实我只是做了一个支持 markdown 的 简易版WunderList
:(。不管怎么样,能坚持下来就是值得鼓励的。整个工程前后端分离,后端实现不在此介绍

前端代码地址

后端代码地址

在线预览

接下来,我简单介绍一下 simplelist 的前端实现过程。注意,下面介绍的一些过程不是一蹴而就,是反复修改和整理得出的,比如技术选择和组件的划分。

编写代码的前期准备工作

有三点

  1. 确定需要实现的功能
  2. 确定界面
  3. 确定技术实现的方案

功能和界面先放一边,介绍一下采用的技术方案。其实也没啥可介绍的,前端老司机花样多,但是主流的套路也就那么几种,我选择“套路のVue”。Vue+
Vuex+ Vue-Router,其他配件像
Less,Webpack等大家也应该都清楚。用户登陆注册及接口的实现不在本文章的讨论中,下次再讲。

组件划分很关键

在 React 的组件化的划分方式中,将组件分成两种:Container Components和Presentational
Components,容器组件和 UI组件。容器组件负责数据和业务逻辑的处理,携带相关的内部状态,与数据有频繁的交互, UI组件只负责 UI
的呈现,没有任何的数据和逻辑的处理,组件的数据从容器组件传递进来(在 React中数据由 this.props 提供)。如果一个组件既有 UI
又有业务逻辑,可以试着将它拆分成两个:一个容器组件,包着一个UI 组件。前者负责与外部的通信,将数据传给后者,由后者渲染出视图。

个人比较喜欢这种方式,组件变得纯粹。不过似乎在 Vue 生态圈中没有设计这方面的介绍,在后面我打算尝试使用这种方式,不过现在还是使用相对粗暴一点的方式来划分。

这是 WunderList 的界面,简单的分析之后,可以将其划分成如下形式,再详细一点的话可以看下图,如果坚持容器组件和
UI组件的形式开发的话,相对较复杂一点,而我选择先从简单的入手。想必你应该看过TodoMVC,而这样也是simplelist
的最简单也是最核心的功能。所以在实际操作过程中,我先将输入框和单个任务这两个组件实现。

Vuex

Vuex 是一个专门为 Vue.js 应用所设计的集中式状态管理架构。它借鉴了 Flux 和 Redux 的设计思想,但简化了概念,并且采用了一种为能更好发挥 Vue.js 数据响应机制而专门设计的实现。

在单独使用 Vue.js
的时候,通常会把状态储存在组件的内部。整个应用的数据和状态都是散落在各个组件。这样并没有有什么问题,组件的数据组建自己管理。有时候状态的一部分需要共享给其他的组件,此时使用事件系统,让一个组件把一些状态“发送”到其他组件,但是当项目一步步扩大时,事件流将变得繁杂,不利于调试和维护。此时
Vuex 可以帮助我们实现状态的管理。

Vuex 的四个核心概念分别是:

  1. The state tree:Vuex
    使用单一状态树,用一个对象就包含了全部的应用层级状态,作为一个『唯一数据源(SSOT)』而存在。每个应用将仅仅包含一个 store
    实例。单状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。数据流都是单向的。
  2. Getters:用来从 store 获取 Vue 组件数据。
  3. Mutators:事件处理器用来驱动状态的变化,只有 mutation 可以改变状态。
  4. Actions:可以给组件使用的函数,用来派发 Mutation。

Vuex 规定,属于应用层级的状态只能通过 Mutation 中的方法来修改,而派发 Mutation 中的事件只能通过
action。从组件出发,组件中调用 action,在 action
这一层级我们可以和后台数据交互,比如获取初始化的数据源,或者中间数据的过滤等。然后在 action 中去派发
Mutation。Mutation 去触发状态的改变,状态的改变,将触发视图的更新。

配合 Vuex 这样的数据管理架构,我只需要关心组件的状态变化,数据的变化和流通全部交给 Vuex。我需要维护一个数组,数组中每一个元素代表一个任务,输入框和任务上的编辑删除等操作,本质上都是对一个数组的操作。

给任务加上分类

我已经说过了,我要做的是复杂的
simplelist。所以,在完成了最简单的增删改的功能之后,要加上任务的自己的归属了。每个任务都归属于一个清单,有唯一的清单
id(list_id)。就像 WunderList 一样,左侧清单列表,右侧任务列表。这时候需要用到单页引用中必不可少的路由装置了。

从简单的开始,除了登录和注册(目前整合在应用中,更好的做法应该是登录注册作为两个单独的页面,这里只是个人 demo,暂不考虑),暂且只有一种路由状态,用来指向对应的清单,例如:/lists/:id。下面是伪代码


  1. <div id="app"> 
  2.   <router-view></router-view> 
  3. </div>  

  1. const ListItem =  { 
  2.   template: `<div class="item">{{item.title}}</div>`, 
  3.     props: ['item'], 
  4. const ListContainer = { 
  5.   template: `<div class="list"> 
  6.       <h2>List {{ $route.params.id }}</h2> 
  7.         <div class="item-list"> 
  8.             <list-item v-for="item in list" :item='item'></list-item>  
  9.         </div> 
  10.     </div>`, 
  11.     components: { 
  12.         'list-item': ListItem, 
  13.     }, 
  14.  
  15. const router = new VueRouter({ 
  16.   routes: [ 
  17.     { path: '/lists/:id', component: ListContainer } 
  18.   ] 
  19. })  

然后绑定好 <router-link>,路由切换就算完成了。但是光这样还不行,最关键的清单数据管理还没有加上。其实清单的数据状态管理与任务的管理大同小异,就不在此复述,你可以试着捋一捋。

弹层组件的管理

在创建和编辑清单的时候,需要弹出一个 modal 来方便操作(参照 WunderList)。这个时候就涉及到一个问题:这种定位不是很清晰的模块,该怎么来管理?

在我看来,这种类型模块大致有两类,一类是全局共享,可能在很多不同的组件中都需要调用,这种全局的我认为可以单独拿出来放在同一个地方供应用调用。另一类是只属于某一个组件,只会在固定的组件中被调用,这类模块推荐直接写在组件中,方便管理,最好是写在顶级组件中,避免一些全七八糟的样式冲突(目前我遇到的主要还是层叠顺序的问题)。

思路清晰之后,可以很顺利的完成清单的创建和编辑功能。

说到这,一个复杂的 simplelist 的基本结构和功能已经出现了。那么问题来了,你学到了吗?

作者:张伦

来源:51CTO

时间: 2024-11-03 22:05:18

如何实现一个稍微复杂的simplelist的相关文章

SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比

原文:SQL点滴10-使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比  今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章,自己添加了一些内容,做了简单的总结,这个语句还是第一次见到,学习了.我从简单到复杂地写,希望高手们不要见笑.下面的sql语句设计到三个表,表的内容我用txt文件复制进去,这里不妨使用上一个随笔介绍的建立端到端的package的方法将这些表导入到数据库中,具体的就不说了. 从这里下载文件emplo

Photoshop绘制一个粉红的燕尾夹

  Photoshop绘制一个粉红的燕尾夹           今天主要分享一下,PS绘制一个粉红的燕尾夹教程.小编习惯是先勾勒形状,再上色,然后再加效果,最后是质感和背景.因为完全是鼠绘,没有使用手绘板之类的东西,所以基本上全部形状都是矢量的,方便后期修改调整. 效果图 先是勾勒形状,这两个造型其实是不会出现在设计中的,分别是主体形状中立体三角形的前一个面和后面一个面,后面一个稍微小一点,符合透视原理吧. 然后画这个有两个角是有点圆角的三角形时是有点小技巧的,如果你PS有形状变圆角的插件,那你

一个门外汉的产品设计漫谈:设计无处不在

本文纯属门外汉YY的结晶,如有低级问题,敬请行家里手批评指正;如果文中煞有介事得出的结论与设计学科的经典理论不谋而合,则不胜荣幸.本文目的是闲侃软件产品尤其是互联网产品的设计,多处以传统产品甚至不登大雅之堂的东东来举例,这顺带也在证明设计无处不在,以及软件设计与传统设计在理念和方法上融会贯通. 设计无处不在,设计决定一切 设计无处不在,人类世界是被设计出来的.如果你细心观察,可以在生活的时时处处发现优秀的设计及其蕴含的智慧.现在低头看看你键盘上F.J两个键上面的小疙瘩;笔记本电脑电源按钮(不是凸

大学毕业的我是如何建立一个成功网站的

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 我刚刚大学毕业,不想去找个安稳的工作,因为我有自己的梦想,想要运营和合承德网,简而言之它是一个关于承德本地生活门户的网站. 如今我学习运营和合承德网已经有一年了,可是效果并不是很好,网站每天的访问流量并不高,所以这也让我的自信心很受打击.虽是如此,我依旧坚信自己的梦想,为了更快.更好掌握做网站的技巧,我翻看了不少过来人写的心得体会,另外也加入

自定义流程的一个问题

问题描述 假设:有单位信息表里面30列的字段.并且每列都是有用的.现在有一个流程的单位信息变动的.在流程开始的地方有录入变动数据的,现在的做法是有个一个跟单位信息表一样的表只是多了一个流程id的表.来控制流程里面的数据,当审批通过就回填到正式表里面.那么问题来了现在要做一个自定义流程.因为需要录入变动数据.又或是其他什么流程需要在流程的开始录入一些数据.这个录入数据的界面怎么来呢?通过自定义表单去做一个然后绑定?假设界面有了.那么录入的数据存入什么地方.因为是自定义的里面可以录入的内容可能分散的

从0开始打造一个独立内存的缓存系统

前言 缓存是后端使用得最多的东西,因为性能是后端开发一个重要的特征,所以缓存就应运而生了,而且现在缓存已经到了泛滥的程度了,我几乎没见过没有缓存的后端,一遇到性能问题,首先想到的不是看代码,而是加缓存,我也是醉了,好了,不扯这些,这些和今天的文章无关,今天我们来专门讲讲缓存吧. 2缓存和KVDB 缓存和KVDB两个东西经常一起出现,两者在使用上没有明显的界限,当一个KVDB速度够快,性能够强劲,那么就可以当缓存来用了,我们使用Redis来做缓存,实际上就是把一个KVDB来当缓存用.但一般情况下,

无停机部署一个 Django 应用

当 healthchecks.io 的流量超过每秒一次访问之后,我就意识到不能随意在部署代码后重启服务了.作为一个监控服务,即使丢掉几个 HTTP 请求也是不应该的.而且,如果服务器变得更加繁忙的话,这个问题只会更加严重. 先简单介绍一下我们所做的工作,这是一个相对简单的 Django 实现的 app,由 gunicorn 来运行,前端是 nginx.数据保存在 PostgreSQL 数据库里.gunicorn和另一个额外的后台进程由 supervisor 负责管理.整个服务在单个$20级别的D

一个高级 PHP 工程师所应该具备的

初次接触PHP,就为他的美所折服,于是一发不可收拾. 很多面试,很多人员能力要求都有"PHP高级工程师的字眼",如果您真心喜欢PHP,并且您刚起步,那么我简单说说一个PHP高级工程师所应该具备的,希望给初级或已经达到中级的PHP工程师一些帮助. 一.平静的心态 和所有程序员一样,要写一手好的程序,没有好的心态是不行的. 遇事不可急躁,不可轻言放弃. 在 程序开发过程中,尤其是初中级程序员,写出的程序或架构会遇到很多问题,其中一些问题比较弱智,而有些问题根本没有碰到过,于是不可太过急躁,

[MySQL5.6] 一个简单的optimizer_trace示例

前面已经介绍了如何使用和配置MySQL5.6中optimizer_trace(点击博客),本篇我们以一个相对简单的例子来跟踪optimizer_trace的产生过程. 本文的目的不是深究查询优化器的实现,只是跟踪optimizer trace在优化器的那一部分输出,因此很多部分只是一带而过,对于需要深究的部分,暂时标注为红色,后续再扩展阅读;之前一直没看过这部分代码,理解起来还是比较困难的- 我们以一个简单的表为例过一下optimizer trace的产生过程: mysql> show crea