以前寫了個小組件, 首先感謝大佬們提的意見, 今天我要總結一下關於開發過程當中, 什麼狀況下咱們要去封裝本身的組件, 固然這個我本身一步步感受出來的, 你們可能也有本身的經驗, 若是你們有更好的方法, 也但願你們能夠不吝賜教留言給我和不當心進來的同窗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就能夠了, 而不用每次都要在前端配置
固然不一樣的公司也會有不一樣的考慮, 仍是但願你們都能有所進步, 也能夠把大家的想法告訴我, 帶我這個渣渣一塊兒進步, 再次感謝