详解vue.js组件化开发实践(9)

如上图所示:左侧容器排列着这些常用组件的标签。将活动需要的组件标签拖入预览区域后,会生成对应的预览组件和编辑组件;点击这个预览组件,组件编辑区域会显示对应的编辑组件;在编辑组件中可以对组件各项进行编辑。编辑完成后,通过事先的数据绑定,预览区域对应的组件就会更新视图,显示组件当前的最新内容。

以上就是这个系统的一个大概方案,下面谈谈具体的实现。

首先,从标签区域开始:

标签组件是每个活动组件的开端,也就说每一个标签组件必须有一个属性来标识它代表的是哪一个活动组件。那就先给它们指定类型 type:

  节标题  type :'sectionTitle'

  投票  type :'vote'

  正文  type :'content'

  用户  type :'user'

  图片  type :'image'

  视频  type :'video'

  音频  type :'audio'

  跳转链接  type :'link'

然后每当我们拖动一个标签组件到预览区域,再根据该标签组件的type生成对应的预览和编辑组件。预览和编辑组件需要确定的无非就是有哪些编辑项,这些编辑项是什么内容。以节标题组件为例,它就只有一个编辑项:节标题的文本。也就是说节标题的预览组件用来显示节标题的文本,编辑组件需要有一个文本域来对节标题文本进行编辑,在模板事先绑定好对应的数据,文本域的数据变化会反应到预览组件的DOM上。

我们需要有一个保存所有组件数据(对象)的容器,可以使用一个数组。

我更喜欢操作一个数组而不是对象的原因:vue对数组的基本方法(push、splice、shift等)都进行了封装,通过这些方法来改变数组的数据,结果都是响应的。而在保持响应的情况下,改变对象的数据要麻烦些,特别是复杂的嵌套对象。如果使用对象可以通过id直接匹配到对应数据,通过数组需要遍历一下。但是有了es6的for of,代码还是很简单,而且也不是在操作DOM,性能影响不大。

//widgetData.js [ {id : "100",type : "vote", ...}, //投票 {id : "101",type : "image", ...}, //图片 {id : "102",type : "video", ...}, //视频 ]

每个组件数据对象的id属性是唯一的,是拖入标签组件时生成的,这个id属性是关联预览组件与对应编辑组件的关键,通过它可以找到每个预览组件对应的编辑组件。为什么不通过type来判断呢?因为每个活动可能有多个相同的组件,比如节标题。通过type没法确定对应关系。

这里我们通过Vuex创建一个store来存储及修改这个数组(官方点的说法就是管理state状态)。按照上面提到的Vuex的数据流规则:UI不允许直接修改数据。在编辑项里面改变某项输入框的值,并不是直接改变了对应组件数据中那一项的值,而是通过DOM事件触发对应的action,action再派发对应的mutaion处理函数来修改state。这种方式可以确保所有对某项组件数据的修改都是通过触发某一个公共的action来完成的,这个action就是进行某项修改的统一和唯一的入口。

当我们知道需要生成什么预览和编辑组件的时候,并放进组件数据容器的时候,我们就必须知道这个组件到底有哪些编辑项(除了组件类型外,我们放入的这个组件数据对象还需要哪些属性),这时候我们就需要一个map,来管理组件type和组件编辑项的关系,以活动的投票组件为例:

根据需求,投票组件需要有以下编辑项:

1.投票的标题

2.投票项,每项要有一个名称,后续每项可能还会有其他属性(类似正确选项的标记等)

//typeDataMap.js export default { vote : { type : "vote", title : "投票标题文本", items : [ {name : "投票项1"}, //每个投票项 {name : "投票项2"}, {name : "投票项3"} ] } }

只要知道是什么类型,通过  typeData[type]  就能获取到组件数据并存入组件数据容器了。由于我们在预览组件和编辑组件的模板视图已事先对DOM进行了数据绑定,当我们改变组件容器中某个组件的数据项时,更新就会反应到DOM上。当我们保存整个模板的时候,只需要取出组件数据容器中的值就行了,其实也就是那个数组本身。H5展示端通过这个组件数据数组,可以拿到组件的数据以及排序,按照定好的模板渲染出来即可。当然,像投票组件这类有交互数据的组件,该系统设计的模板只是确定了要展示的固定的内容。具体的投票总数、每项投票数等属性需要后端处理后插入到对应组件数据里面,供展示端显示。

整个系统大概的设计思想就是这样的,下面挑些具体的来讲讲:

 标签组件

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwfgpj.html