资讯专栏INFORMATION COLUMN

实现一个稍微复杂的simplelist

solocoder / 418人阅读

摘要:是一个专门为应用所设计的集中式状态管理架构。此时可以帮助我们实现状态的管理。每个任务都归属于一个清单,有唯一的清单。说到这,一个复杂的的基本结构和功能已经出现了。

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

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

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

前端代码地址,
后端代码地址,
在线预览。

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

编写代码的前期准备工作

有三点

确定需要实现的功能

确定界面

确定技术实现的方案

功能和界面先放一边,介绍一下采用的技术方案。其实也没啥可介绍的,前端老司机花样多,但是主流的套路也就那么几种,我选择“套路の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 的四个核心概念分别是:

The state tree:Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态,作为一个『唯一数据源(SSOT)』而存在。每个应用将仅仅包含一个 store 实例。单状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。数据流都是单向的。

Getters:用来从 store 获取 Vue 组件数据。

Mutators:事件处理器用来驱动状态的变化,只有 mutation 可以改变状态。

Actions:可以给组件使用的函数,用来派发 Mutation。

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

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

给任务加上分类

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

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

const ListItem =  {
  template: `
{{item.title}}
`, props: ["item"], } const ListContainer = { template: `

List {{ $route.params.id }}

`, components: { "list-item": ListItem, }, } const router = new VueRouter({ routes: [ { path: "/lists/:id", component: ListContainer } ] })

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

弹层组件的管理

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

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

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80486.html

相关文章

  • 翻译连载 | JavaScript 轻量级函数式编程-第5章:减少副作用 |《你不知道JS》姊妹篇

    摘要:函数式编程者并没有消除所有的副作用。我的结论是这里的并不违反减少或避免副作用的精神。一些语言允许你指定生成随机数的种子。因此,我们必须将内建的随机数生成视为不纯的一方。其他的错误在程序运行期间副作用可能导致的错误是多种多样的。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 关于译者:这是一个流淌...

    yeyan1996 评论0 收藏0
  • React.js 小书 Lesson1-2 - 前端组件化(一):从一个简单例子讲起

    摘要:一个组件的显示形态和行为有可能是由某些数据决定的。一个简单的点赞功能我们会从一个简单的点赞功能讲起。我们需要结构,准确地来说我们需要这个点赞功能的字符串表示的结构。下一节小书前端组件化二优化操作中我们继续优化这个例子,让它更加通用。 React.js 小书 Lesson1-2 - 前端组件化(一):从一个简单的例子讲起 本文作者:胡子大哈本文原文:http://huziketang....

    null1145 评论0 收藏0
  • ArrayList 源码详细分析

    摘要:源码分析构造方法有两个构造方法,一个是无参,另一个需传入初始容量值。所以我们可以把上面的代码转换一下,等价于下面形式这个时候,我们再去分析一下的迭代器源码就能找出原因。原因是删除元素后,元素计数器,而迭代器中的也等于,从而导致返回。 1.概述 ArrayList 是一种变长的集合类,基于定长数组实现。ArrayList 允许空值和重复元素,当往 ArrayList 中添加的元素数量大于...

    W4n9Hu1 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<