谈谈「数据模型」是如何助力前端开发的

1、定义

数据模型是数据特征的抽象,用来抽象定义一个业务对象。假如如今有一个用户模型,若是要抽象的描述这个用户对象,能够按照以下来定义:前端

const UserModel = {
    name:{
        type:String,
        property:'name',
        value:'zhangshang'
    },
    age:{
        type:Number,
        property:'age',
        value:26
    }
}

复制代码

其中,type声明数据的类型,property指明映射路径,value是默认值。这里先有个大概的概念就行,后面我会经过实例来详细展开。vue

2、动机

前面介绍了数据模型的定义,那和前端开发又有什么关系呢?前端又不须要和数据库打交道,前端开发主要就是拿到数据显示就完了,那为何须要数据模型呢?它是怎么助力前端开发的呢?咱们先来看一下如下几个场景。ios

场景一

咱们在前端开发中,经过ajax请求拿到服务端数据,而后将数据显示在视图上,常常会写以下代码:git

如示例,假如咱们要显示用户头像,经过取到headUrl的值绑定在src属性上便可。由于是异步加载获取的数据,在最终获取到headUrl的值以前,咱们须要先判断cardData.buyerExperienceInfo的存在性,而后才能取值,不然在视图初次渲染以前会报以下错误:github

在这种场景下,咱们在开发中就不得不写一些防护性的代码,长此以往,项目中相似代码会愈来愈多,碰到层级深的,防护性代码就会写的愈来愈恶心。另外还有的就是,若是服务端在这中间某个字段删掉了,那就又得特殊处理了,不然会有一些未知的非空错误报错,这种编码方式会致使前端严重依赖服务端定义的数据结构,很是不利于后期维护。ajax

场景二

平时开发中,咱们拿到了服务端返回的数据,有些不是标准格式的,是没法直接在视图上直接使用的,是须要而外格式化处理的,好比我司服务端返回的的价格字段单位统一是,跟时间相关的字段统一是毫秒值,这个时候咱们在组件的生命周期内,就不得不而外增长一些对数据处理的逻辑,还有就是这部分处理在不少组件都是公用的,咱们就不得不频繁编写相似的代码,数据处理逻辑没有获得复用数据库

场景三

在用户作了一些交互后,须要将一些数据存储到服务端,这个时候咱们拿到的数据每每也是非标准的,就好比你要提交个表单,其中有个价格字段,你拿到价格单位多是百位的,而服务端须要的单位必须是分位的,这个时候在提交数据以前,你又得对这部分数据进行处理,还有就是有些接口的参数是json字符串形式的,多是多级嵌套的,你还要须要特地构造这样的参数数据格式,致使开发中编写了太多与业务无关的逻辑,随着项目逐渐扩大或者维护人员更迭,项目会愈来愈很差维护。json

3、数据模型

在碰到这么多痛点以后,我就在想如何解决,回顾以上场景,总结下来存在如下几个问题:axios

  1. 先后端数据结构没有解耦,前端在应对不定的服务端数据结构前提下,须要编写过多的保护性代码,不利于维护的同时,代码健壮性也不高。
  2. 基础数据逻辑处理没有和UI视图解耦,容易阻塞视图渲染,同时,在视图组件上存在太多的基础数据逻辑处理,没有有效复用。

因此,这里我引入了数据模型的概念,那经过数据模型如何解决这类问题呢?下面我将经过两个实际案例来进一步呈现上述场景,以及引入了数据模型以后是如何解决的。后端

4、案列功能

这个案例使用Vue开发,功能很简单,就是经过ajax请求从服务端拿到数据,而后经过vue视图进行展示,效果以下:

5、常规实现

代码只展现主要功能代码,非完整实现

1.请求数据

created生命周期内,向服务端请求数据。

2.数据处理

获取到数据以后,由于拿到的数据和最终UI上显示的格式不一致,须要转化一下数据格式。

3.渲染数据

给当前Vue实例赋值,而后在template里经过模板语法进行渲染

能够看到常规写法,模板语法里面的写法特别不优雅,各类保护性代码(条件判断)

6、经过数据模型方式处理

1.定义数据模型

首先,咱们能够专门建一个名叫model的文件夹,专门用来存放模型,而后定义卡片模型cardModel,其中数据定义格式以下:

  1. type 必填,用来描述该字段的类型,支持String、Number、Date等类型
  2. property 必填,数据路径,对应服务端数据结构的取值路径
  3. value 选填,数据默认值,可不填

经过new Model()进行初始化,后续只须要经过model.parse(data)或者model.traverse(data)这个两个方法就能够完成正向映射和反向映射的过程。

具体的使用方式能够查看API

2.请求数据

经过axios请求接口,在拿到数据以后,调用parse方法解析数据,在解析的过程当中会去作赋值操做以及数据格式化。

3.数据渲染

拿到数据,赋值给vue组件实例后,在template模板里面直接使用咱们事先定义好的数据字段,不须要再去写相似a&a.b&a.b.c这样的代码,且无论服务端数据字段如何变化,视图渲染都不受影响,从而实现和服务端数据结构进行解耦。

与此同时,针对相似价格、时间等须要格式化的数据,咱们能够直接使用,不须要再去写对应的格式化处理逻辑,从而专一于视图组件渲染处理。

经过引入数据模型,咱们能够看到在模板里面引入变量的时候不须要进行各类判断,写法很是优雅,并且健壮性很强,即便服务端某个字段没有返回,咱们这里也不会所以存在报错的可能性。且在脚本里面没有了数据格式化处理代码,从而不会由于数据处理逻辑代码可能存在的错误,打断UI的渲染。从而带来的更大好处是,随着项目的不断迭代,数据和视图有着清晰的划分,前端和后端进行了解耦,项目的可维护性获得保证。

4.反向映射

在库里面,还提供了traverse方法,和parse方法相似,区别是traverse是反向数据生成以及格式还原。

7、模型库的原理

最后,我来说讲这个数据模型库(ducker-model)的实现原理,源码总共不到200行,仍是简单的,能够经过这里下载查看,主要实现逻辑以下:

  1. 声明一个名叫Model的类。
  2. 经过new Model(options),传入模型结构,初始化数据模型属性,对外主要使用的是parsetraverse方法,
  3. parse方法的实现过程就是遍历模型数据结构,拿到每一个属性的数据路径,而后根据这个路径去取传入的的数据里面的数据,最后给事先定义好的属性赋值,在赋值的过程当中,能够根据type格式化一些相似时间、价格类型的数据。
  4. traverse方法恰好和parse相反,一样是遍历数据模型结构,拿到每一个属性的数据路径,而后根据这个数据路径去设置一个新对象的值,这期间,反向格式化数据类型,最后返回这个新对象。

8、更进一步

目前这个库还很基础,只支持了一些常规的功能,能作的事情还不少,好比:

  1. 目前每次拿到请求一次数据以后都须要解析一次,那是否有个缓存机制,在数据没有变更的时候,直接从缓存取数据呢,或者能够直接watch这个解析以后的数据,作到数据变更,视图变更呢?
  2. 现有支持的类型还不够多,能够根据具体业务状况增长一些类型,以应对更多场景,提供可扩展的机制。
  3. 插件机制,好比表单处理,咱们是否能够在数据模型定义的时候就定义好字段格式,在提交的时候就能够直接进行格式检测,抛出提醒呢?
  4. 目前的操做方式还比较适合纯粹的渲染式组件,如何和复杂的携带业务交互的组件融合也是须要考虑的。
  5. ... ...

文章末尾会提供模型库下载地址,有须要的能够在此基础上进行扩展,欢迎一块儿完善这个库,另外,案例demo的地址也提供了,欢迎下载学习理解。

9、源码下载

案例:ducker-model-demo

模型库:ducker-model

相关文章
相关标签/搜索