Vue相信玩前端的小伙伴一定不会陌生。使用Vue最大的好处就是组件化,通过组件的复用可以大大减小我们日常开发的工作量。最近在工作中遇到这样的情况,于是便趁着周末正好将自己写的组件整理一下,做成更加通用的组件。
先介绍一下背景。这段时间因为工作上的需要,要做后台管理系统,这类系统相信很多小伙伴也很熟悉。主要以表单的填写以及表格的展示、编辑为主。前端这一部分采用Vue全家桶,UI组件采用的是iview。UI组件大大提高了开发效率以及降低了开发的复杂度,但是组件也不是万能的,在面对实际的业务时,还是需要靠我们自己来制作组件。而这一次要制作的组件就是可以根据传入的数据不同,自动生成不同样式的表单以及表格了。(当然,利用的组件还是基于iview的)
制作思路
组件的本质就是拼装。通过拼装一个个原子组件,形成一个大组件最后来满足我们的实际业务需求。而在我这一次的需求中,原子组件已经有iview提供了。我要做的就是怎样来制作出想要的表单以及表格了。Vue提倡的思想就是数据驱动,所以在与其说是拼装组件,更不如说是设计一个合理的数据结构。
首先是表单,通过v-for对数据进行循环,然后判断数据对应的表单组件类型就可以了。因此我们需要的数据结构就需要组件的类型、绑定的值、值对应的变量名(类似username:'用户'),而其他的属性就可以根据需要再做追加。
再是表格,同样也是通过v-for对数据进行循环展示。在编辑时也需要切换到对应的组件。因此与表单的数据结构设计相同,我们需要组件的类型、绑定的值、值对应的变量名(类似username:'用户')。
而其中的难点,无非就是在于行数和列数的计算上了。怎么灵活地变换行数,还是需要利用到v-for循环中的index来进行帮忙。相信这些,只要看过一眼代码就马上可以理解。
// commonForm 代码
// commonTable 代码
{{_detialData.tableHeader}}
{{_dataList[Math.floor(((rownum - 1) * _colNum + colIndex) / 2)].title}}
{{_dataList[Math.floor(((rownum - 1) * _colNum + colIndex) / 2)].value}}
{changeDateTime(datetime, _dataList[Math.floor(((rownum - 1) * _colNum + colIndex) / 2)])}">
{changeDateTime(datetime, _dataList[Math.floor(((rownum - 1) * _colNum + colIndex) / 2)])}">
{changeDateTime(datetime, _dataList[Math.floor(((rownum - 1) * _colNum + colIndex) / 2)])}">
{changeDateTime(datetime, _dataList[Math.floor(((rownum - 1) * _colNum + colIndex) / 2)])}">
项目地址:my-components 项目主页上也有相关的说明。这里就不做赘述了。
说完了思路那么还是一如既往,先来看看效果直接感受一下吧。
表单组件 commonForm
当我们传入如下数据格式的数据后,就会生成这样的表单。
mockForm: [
{ title: '输入框', name: 'text', type: "text", placeholder: '请输入输入框内容', value: '' },
{
title: '地区级联菜单', name: 'cascader', type: "cascader", placeholder: '请选择地区', data: [{
value: 'shanghai', label: '上海', children: [
{ value: 'huangpu', label: '黄浦区' },
{ value: 'huangpu', label: '普陀区' },
{ value: 'huangpu', label: '静安区' },
{ value: 'huangpu', label: '闸北区' }
]
}, {
value: 'shanghai', label: '上海', children: [
{ value: 'huangpu', label: '黄浦区' },
{ value: 'huangpu', label: '普陀区' },
{ value: 'huangpu', label: '静安区' },
{ value: 'huangpu', label: '闸北区' }
]
}],
value: []
},
{ title: '下拉框选项', name: 'select', type: "selection", selection: [{ title: '选项一', value: '选项一' }, { title: '选项二', value: '选项二' }], placeholder: '请选择选项', value: '' },
{ title: '日期时间', name: 'datetime', type: "datetime", placeholder: '请输入日期', value: '' },
{ title: '日期时间范围', name: 'datetimerange', type: "datetime-range", placeholder: '请输入日期', value: '' },
{ title: '日期范围', name: 'daterange', type: "date-range", placeholder: '请输入日期', value: '' },
{ title: '时间范围', name: 'timerange', type: "time-range", placeholder: '请输入时间范围', value: [] },
{ title: '输入框', name: 'textarea', type: "textarea", placeholder: '请输入客户的简介', value: '' },
],
表格组件 commonTable
当我们传入如下数据格式的数据后,就会生成这样的表格。点击编辑后会转为编辑模式。
mockTable: {
tableHeader: '表格标题',
dataList: [
{ title: '输入框', name: 'input', value: '点击编辑后为输入框', edit_type: 'text' },
{
title: '级联菜单', name: 'cascader', value: ['shanghai', 'huangpu'], edit_type: 'cascader', data: [{
value: 'shanghai', label: '上海', children: [
{ value: 'huangpu', label: '黄浦区' },
{ value: 'huangpu', label: '普陀区' },
{ value: 'huangpu', label: '静安区' },
{ value: 'huangpu', label: '闸北区' }
]
}, {
value: 'beijing', label: '北京', children: [
{ value: 'huangpu', label: '天安门' },
{ value: 'huangpu', label: '故宫' },
{ value: 'huangpu', label: '颐和园' },
{ value: 'huangpu', label: '紫禁城' }
]
}]
},
{ title: '下拉菜单', name: 'select', value: '是', edit_type: 'selection', selection: [{ title: '是', value: '是' }, { title: '否', value: '否' }] },
{ title: '日期时间', name: 'datetime', value: '2017-01-01 01:30', edit_type: 'datetime' },
{ title: '日期时间范围', name: 'datetimerange', value: '2017-01-01 01:30', edit_type: 'datetime-range' },
{ title: '日期范围', name: 'daterange', value: '2017-01-01 01:30', edit_type: 'date-range' },
{ title: '时间范围', name: 'timerange', value: '2017-01-01 01:30', edit_type: 'time-range' },
{ title: '块级输入框', name: 'textarea', value: '这是块级输入框', edit_type: 'textarea' }
]
}
最后,现在这两个组件只是目前在我自己的项目中会比较常用。灵活性以及适用性还不够广泛(比如缺乏校验,表单的格式等),同时由于依赖iview,一些iview上组件的bug也同样会有。如果各位小伙伴有好的建议,也欢迎来交流。