数据模型是数据特征的抽象,用来抽象定义一个业务对象。假如如今有一个用户模型,若是要抽象的描述这个用户对象,能够按照以下来定义:前端
const UserModel = {
name:{
type:String,
property:'name',
value:'zhangshang'
},
age:{
type:Number,
property:'age',
value:26
}
}
复制代码
其中,type
声明数据的类型,property
指明映射路径,value
是默认值。这里先有个大概的概念就行,后面我会经过实例来详细展开。vue
前面介绍了数据模型的定义,那和前端开发又有什么关系呢?前端又不须要和数据库打交道,前端开发主要就是拿到数据显示就完了,那为何须要数据模型呢?它是怎么助力前端开发的呢?咱们先来看一下如下几个场景。ios
咱们在前端开发中,经过ajax
请求拿到服务端数据,而后将数据显示在视图上,常常会写以下代码:git
如示例,假如咱们要显示用户头像,经过取到headUrl
的值绑定在src
属性上便可。由于是异步加载获取的数据,在最终获取到headUrl
的值以前,咱们须要先判断cardData.buyerExperienceInfo
的存在性,而后才能取值,不然在视图初次渲染以前会报以下错误:github
在这种场景下,咱们在开发中就不得不写一些防护性的代码,长此以往,项目中相似代码会愈来愈多,碰到层级深的,防护性代码就会写的愈来愈恶心。另外还有的就是,若是服务端在这中间某个字段删掉了,那就又得特殊处理了,不然会有一些未知的非空错误报错,这种编码方式会致使前端严重依赖服务端定义的数据结构,很是不利于后期维护。ajax
平时开发中,咱们拿到了服务端返回的数据,有些不是标准格式的,是没法直接在视图上直接使用的,是须要而外格式化处理的,好比我司服务端返回的的价格字段单位统一是分,跟时间相关的字段统一是毫秒值,这个时候咱们在组件的生命周期内,就不得不而外增长一些对数据处理的逻辑,还有就是这部分处理在不少组件都是公用的,咱们就不得不频繁编写相似的代码,数据处理逻辑没有获得复用。数据库
在用户作了一些交互后,须要将一些数据存储到服务端,这个时候咱们拿到的数据每每也是非标准的,就好比你要提交个表单,其中有个价格字段,你拿到价格单位多是百位的,而服务端须要的单位必须是分位的,这个时候在提交数据以前,你又得对这部分数据进行处理,还有就是有些接口的参数是json
字符串形式的,多是多级嵌套的,你还要须要特地构造这样的参数数据格式,致使开发中编写了太多与业务无关的逻辑,随着项目逐渐扩大或者维护人员更迭,项目会愈来愈很差维护。json
在碰到这么多痛点以后,我就在想如何解决,回顾以上场景,总结下来存在如下几个问题:axios
因此,这里我引入了数据模型的概念,那经过数据模型如何解决这类问题呢?下面我将经过两个实际案例来进一步呈现上述场景,以及引入了数据模型以后是如何解决的。后端
这个案例使用Vue开发,功能很简单,就是经过ajax请求从服务端拿到数据,而后经过vue视图进行展示,效果以下:
代码只展现主要功能代码,非完整实现
在created
生命周期内,向服务端请求数据。
获取到数据以后,由于拿到的数据和最终UI上显示的格式不一致,须要转化一下数据格式。
给当前Vue
实例赋值,而后在template
里经过模板语法进行渲染
能够看到常规写法,模板语法里面的写法特别不优雅,各类保护性代码(条件判断)
首先,咱们能够专门建一个名叫model的文件夹,专门用来存放模型,而后定义卡片模型cardModel
,其中数据定义格式以下:
type
必填,用来描述该字段的类型,支持String、Number、Date等类型property
必填,数据路径,对应服务端数据结构的取值路径value
选填,数据默认值,可不填经过new Model()
进行初始化,后续只须要经过model.parse(data)
或者model.traverse(data)
这个两个方法就能够完成正向映射和反向映射的过程。
具体的使用方式能够查看API
经过axios请求接口,在拿到数据以后,调用parse
方法解析数据,在解析的过程当中会去作赋值操做以及数据格式化。
拿到数据,赋值给vue
组件实例后,在template
模板里面直接使用咱们事先定义好的数据字段,不须要再去写相似a&a.b&a.b.c
这样的代码,且无论服务端数据字段如何变化,视图渲染都不受影响,从而实现和服务端数据结构进行解耦。
与此同时,针对相似价格、时间等须要格式化的数据,咱们能够直接使用,不须要再去写对应的格式化处理逻辑,从而专一于视图组件渲染处理。
经过引入数据模型,咱们能够看到在模板里面引入变量的时候不须要进行各类判断,写法很是优雅,并且健壮性很强,即便服务端某个字段没有返回,咱们这里也不会所以存在报错的可能性。且在脚本里面没有了数据格式化处理代码,从而不会由于数据处理逻辑代码可能存在的错误,打断UI的渲染。从而带来的更大好处是,随着项目的不断迭代,数据和视图有着清晰的划分,前端和后端进行了解耦,项目的可维护性获得保证。
在库里面,还提供了traverse
方法,和parse
方法相似,区别是traverse
是反向数据生成以及格式还原。
最后,我来说讲这个数据模型库(ducker-model
)的实现原理,源码总共不到200行,仍是简单的,能够经过这里下载查看,主要实现逻辑以下:
Model
的类。new Model(options)
,传入模型结构,初始化数据模型属性,对外主要使用的是parse
和traverse
方法,parse
方法的实现过程就是遍历模型数据结构,拿到每一个属性的数据路径,而后根据这个路径去取传入的的数据里面的数据,最后给事先定义好的属性赋值,在赋值的过程当中,能够根据type
格式化一些相似时间、价格类型的数据。traverse
方法恰好和parse
相反,一样是遍历数据模型结构,拿到每一个属性的数据路径,而后根据这个数据路径去设置一个新对象的值,这期间,反向格式化数据类型,最后返回这个新对象。目前这个库还很基础,只支持了一些常规的功能,能作的事情还不少,好比:
watch
这个解析以后的数据,作到数据变更,视图变更呢?文章末尾会提供模型库下载地址,有须要的能够在此基础上进行扩展,欢迎一块儿完善这个库,另外,案例demo的地址也提供了,欢迎下载学习理解。
模型库:ducker-model