以前写了个小组件, 首先感谢大佬们提的意见, 今天我要总结一下关于开发过程当中, 什么状况下咱们要去封装本身的组件, 固然这个我本身一步步感受出来的, 你们可能也有本身的经验, 若是你们有更好的方法, 也但愿你们能够不吝赐教留言给我和不当心进来的同窗html
好了很少bb, 此次我是来解析封装多行编辑组件的前端
多行编辑组件, 通常在管理系统的大表单中出现的概率比较大, 并且业务越复杂的表单越有概率出现他的身影, 部分人可能还没听过这个东西, 我先介绍一下吧, 这个东西也叫"动态增减表单项", 就是这个东西vue
再element-ui中是这样的react
网上对这个东西的介绍只能算通常多吧, jquery封装的组件可能多一点, 框架的UI虽然也有封装, 可是功能都偏少jquery
好了如今又到了咱们会1+1, 就要算微积分了的时候了, 固然咱们也不能凭空去算, 至少看一下前人的经验, 我看过稍微完整一点的就是Ant Design Pro管理系统模板的, 固然这个是react的, 可是无所谓是用的什么框架, 咱们先看一下他的git
功能挺多的了, 并且他是在表格中实现的, 看起来比较整齐, 固然用Layout布局也能够, 都没什么问题, 我此次就站在巨人肩膀上用element-ui的表格布局实现如下他这个吧, 毕竟咱们要作vue的多行编辑功能, 先总结他的已有功能吧, 而后我再添加点github
好, 有了整理咱们就很清楚了, 具体什么用什么功能的组件, 可是这些并不能知足咱们的需求, 咱们还要再添加一点功能数据库
这里也引出一个点, ui库已经给你封装好了你就复制粘贴嵌套一下就行了, 为何还要画蛇添足?element-ui
我大致来回答一下, 咱们的开发与封装就是要基于业务和开发便利以及便于维护为目的, 而ui框架的开发更多的是为了去适应更多的人使用, 更加便利易懂 打个比喻: ui库不是作出一个个"人", 而是要作出一个个骨架, 一种种外貌, 让咱们本身去捏人捏脸, 让咱们本身拼接 而融入到业务中, 咱们在这样是不可以达到最大方便的, 咱们在业务中就是要吧这些零散的骨架适当组装, 组装出可能用到的各类腿, 各类胳膊, 身子, 美丽且满满头发的脑壳瓜, 咱们再去拿这些拼人就行了, 原来咱们要ui的零散的好多拼成一个页面, 如今咱们只要拿几个稍大的功能组件一组就够了, 可能不少人在本身的开发中已经应用了这种方法, 没问题, 我以为这么作有点棒棒的json
开始操做起来, 不过我相信你已经明白该怎么作了, 下面仍是按照上一篇文档的节奏来写, 咱们如今已经总结完功能了, 接下来咱们就是要设计基本的结构
<div>
<table>
<!-- 表头 -->
<thead>
<td></td> *n
</thead>
<!-- 内容 -->
<tr>
<td> *n
<input>
</td>
<!-- 控制列 -->
<td>
<button>确认</button>
<button>取消</button>
<button>删除</button>
<button>编辑</button>
</td>
</tr>
</table>
<button>新增一行</button>
</div>
复制代码
*n的地方表明了接下来咱们要用循环建立
把结构一屡, 没多少东西, 接下来咱们就要肯定哪些东西是要外部控制的
先插入一点原理, 这个多行编辑是怎么实现的 再vue中, 咱们经过v-for循环建立一组对应的标签, 因此若是咱们对循环的那个变量不断的push新的值天然就会被v-for渲染到页面, 好了继续整理
简单写一下这个
methods:{
pushlist() {
//添加一行
},
editstatus(index){
//控制单行的开关状态
},
delrow(index) {
//删除本行
},
cancelrest(index, sw, row) {
//取消时恢复本行
},
}
复制代码
整理了方法, 咱们就要看看这些方法中, 以及应用中要用到哪些从外部传入的参数呢
<div id="inputList">
<!-- 由于要作rule验证, 因此要有form -->
<el-form :model="listModel">
<!-- 表格, tableData为多行编辑的数据, 咱们要用他的长度渲染表格有几行因此要绑定data -->
<el-table :data="listModel.tableData" style="width: 100%" size="mini">
<!-- 在element-ui中的table是自动绑定列名称的,因此就合成一个数组rowTable中 -->
<el-table-column v-for="(item,index) in rowTable" :key="index" :label="item.label" :width="item.width">
<!-- 要获取单行数据进行处理, 因此要绑定scope -->
<template slot-scope="scope">
<!-- 当只展现时, 用span进行展现 -->
<span v-show="scope.row.status">{{ scope.row[item.prop] }}</span>
<!-- 编辑时, 用form + input等方式编辑 -->
<el-form-item v-show="!scope.row.status" :prop="'tableData.'+scope.$index+'.'+item.prop" :rules="item.rule"
:ref="'tableData.'+scope.$index+'.'+item.prop">
<el-input size="mini" v-model="listModel.tableData[scope.$index][item.prop]"
v-if="item.type == 'text' || !item.hasOwnProperty('type')" :disabled="item.disabled"></el-input>
</el-form-item>
</template>
</el-table-column>
<!-- 单独一列, 操做列 -->
<el-table-column label="操做">
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.$index, scope.row.status, scope.row)">
{{scope.row.status?'编辑':'肯定'}}</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 新增一行操做 -->
<el-button size="mini" @click="addRowList" class="addBtn">新增一行</el-button>
</el-form>
</div>
复制代码
{
//显示的名称
label: "邮箱",
//input宽度
width: "180",
//绑定prop
prop: "email",
//验证规则
rule: [{ required: true, message: "年龄不能为空" }],
//input类型 "number", "date", "text", "search", "select", 暂时想了这么多, search就是上一篇的类型
type: "number",
//是否容许编辑, 有的内容是只由别的带出来, 只能看或者修改别的框改变这个, 因此此框禁用
disabled: false
},
复制代码
// form绑定的数据
listModel: {
//表格绑定的数据
tableData: [
{
//表格一行的数据
email: "email1@qq.com",
email1: "",
email2: "email2@qq.com",
email3: "email3@qq.com",
email4: "email4@qq.com",
email5: 123,
//开关, 决定是不是展现状态仍是编辑状态, disabled禁用属于编辑状态
status: false,
//肯定每一行惟一的key
key: new Date().getTime()
}
]
}
复制代码
cancelListData:[
{
//表格一行的数据
email: "email1@qq.com",
email1: "",
email2: "email2@qq.com",
email3: "email3@qq.com",
email4: "email4@qq.com",
email5: 123,
status: false,
//肯定每一行惟一的key
key: new Date().getTime()
}
]
复制代码
methods:{
addRowListJudge(){
// 判断是否有未操做完的行, 而后才容许新增一行, 也是为了提交表单时判断更为简便
},
handleEdit(){
// 调用传入的修改状态的方法
},
handleCancel(){
// 调用传入的取消方法
},
handleDelete(){
// 调用传入的删除行的方法
},
}
复制代码
a. 第一个就是浅拷贝深拷贝的问题, 有不少人说浅拷贝深拷贝有啥用, 平时也基本遇不到, 这里就给了一个例子, 代码中有注释, 具体会遇到什么问题, 我在这里说一下, 当我在从不可编辑变为可编辑的时候我要先备份一下当前行, 便于点取消的时候可以恢复, 若是我用了浅拷贝, 这个数组里的内容指向的仍是同一个地址, 当我改变当前行的时候, 其实我备份的那个也已经变了, 因此就不能恢复了, 即一个动, 全都动, 因此这里要画个重点
b. 第二个就是vue视图更新的问题, 数组内容更新, vue视图是不会自动更新的, 具体能够查看官网的cn.vuejs.org/v2/guide/re…, 因此用splice去处理数组, 固然还有好多办法, splice比较简单
c. 关于业务封装组价的问题, 由于每一个人的业务是不一样的, 作出符合各类功能的组件是很难的, 因此各个ui库会尽可能的把功能拆分的细小一点, 也会更加灵活, 而咱们在实际业务开发中, 咱们想要的是更加节省时间, 因此在原有细小的基础上作一些相对功能丰富一点, 并且更易于配置的组件, 像这个组件, 咱们除了在开发中调用它, 咱们甚至只要几个空间, 在数据库中配置这个大json就能够了, 而不用每次都要在前端配置
固然不一样的公司也会有不一样的考虑, 仍是但愿你们都能有所进步, 也能够把大家的想法告诉我, 带我这个渣渣一块儿进步, 再次感谢