前言
vue的UI框架非常多,我司后臺(tái)主要是用餓了么團(tuán)隊(duì)的element ui(http://element.eleme.io/#/zh-CN)開發(fā)的,順便吐槽下之前開發(fā)移動(dòng)端用的是餓了么的mint ui,坑賊多,有空整理下。。。。
業(yè)務(wù)場(chǎng)景
可以簡(jiǎn)單理解為一個(gè)專場(chǎng)拼接的功能,可以往里面插入各種模塊。左邊是預(yù)覽區(qū),右邊是控制區(qū)(木圖幫助大家腦補(bǔ)下emmm),一個(gè)模塊可以插入很多次,我們這里就當(dāng)只插入商品模塊,商品模塊的控制區(qū)域(展示商品小圖預(yù)覽然后可以刪除),點(diǎn)擊+號(hào)彈出彈層選擇商品。
算了還是上個(gè)圖吧

彈窗就不放了,element ui 帶多選框分頁(yè)器的demo就是
把這塊拆分出來(lái),就是預(yù)覽區(qū)的此模塊為父級(jí)組件(其上還有預(yù)覽區(qū)為最頂級(jí)組件),控制區(qū)域?yàn)樽咏M件,彈層為子組件調(diào)用的模塊
關(guān)于數(shù)據(jù)的問(wèn)題的話可以使用vuex也可以$emit往上一級(jí)一級(jí)傳就不細(xì)說(shuō)了。
DOM結(jié)構(gòu)
<el-table ref="productTable" :data="list" @selection-change="select" @select="choserow" border show-overflow-tooltip stripe>
<el-table-column
label-class-name="table_header"
label="全選"
type="selection"
header-align="center"
width="100"></el-table-column>
<el-table-column
label-class-name="table_header"
label="商品名稱"
prop="name"
header-align="center"
width="555">
<template slot-scope="scope">
<img class="productImg" :src="scope.row.img_cover" alt="商品主圖">
<p class="productP">
<a>{{ scope.row.title }}</a><br>
</p>
</template>
</el-table-column>
<el-table-column
label-class-name="table_header"
label="項(xiàng)目類型"
prop="product_type"
header-align="center"
width="150"></el-table-column>
<el-table-column
label-class-name="table_header"
label="上架時(shí)間"
prop="online_date"
header-align="center"
width="250"></el-table-column>
<el-pagination class="page" ref="elPagition"
background
layout="prev, pager, next"
:total="pagination.total"
:page-size="+pagination.page_size"
:current-page="pagination.page"
@current-change="page"
></el-pagination>
</el-table>
數(shù)據(jù)
data() {
return {
is_visible: false, // todo: 彈層是否可以顯示
list: [], // 列表數(shù)據(jù)源
selected: [], // 真實(shí)選中的值,用于最后返回
pagination: {
page: 1,
page_size: Number,
total: 1
},
menu1List: [], //篩選相關(guān) 三級(jí)層連
menu2List: [],
itemList: [],
checkList: [], // 記錄之前選中的
title: '', // 搜索后不清空雙向綁定的值
tname: '', // 同上,拿來(lái)搜索的值
form: {
item_id: '',
menu1_id: '',
menu2_id: '',
}
}
},
功能梳理
1、表格經(jīng)過(guò)搜索、分頁(yè)后,數(shù)據(jù)保留
table綁定的selection-change只能拿到當(dāng)前表格選中的值,因此要設(shè)置兩個(gè)數(shù)組。每次觸發(fā)selection-change將當(dāng)前結(jié)果放入selected,當(dāng)list重新刷新之前,處理checkList
this.checkList = this.unique( this.checkList.concat( this.selected ) )
unique( arr ) {
// 帶有g(shù)etset的對(duì)象似乎不能用es6數(shù)組去重
// return Array.from(new Set(arr))
// const res = new Map();
// return arr.filter((a) => !res.has(a) && res.set(a, 1))
let hash = {}
return arr.reduce( function ( item, next ) {
hash[next.pid] ? '' : hash[next.pid] = true && item.push( next )
return item
}, [] )
},
2、自動(dòng)勾選
很顯然我們這個(gè)需求是可以選中已有模塊,此時(shí)彈窗時(shí)數(shù)據(jù)應(yīng)同步到table中并選中相應(yīng)元素。其次在換頁(yè)、重新搜索時(shí),也應(yīng)把checkList內(nèi)的值重新選中。
因?yàn)閷?shí)在沒(méi)找著column api里有關(guān)于默認(rèn)勾選的設(shè)置,或許是我眼瞎,求指正。。。 就只能在頁(yè)面組件load、list刷新時(shí)手動(dòng)勾選。
//其他組件可以通過(guò)調(diào)用此ref的load()來(lái)調(diào)出
load( ...rest ) {
...//通過(guò)參數(shù)傳好checkList后
this.autoSelect( this.checkList )
},
autoSelect( arr ) {
this.$nextTick( () => {
if ( this.list !== undefined && arr !== undefined ) {
this.list.forEach( ( v, i ) => {
arr.forEach( ( _v, _i ) => {
if ( v.pid === _v.pid ) {
this.$refs.productTable.toggleRowSelection( v, true )
}
} )
} )
}
} )
},
3、切換模塊table重置
table模塊只存在一個(gè),因此每次load的時(shí)候都需要重置搜索條件、page。但是手動(dòng)修改data里面的current-page對(duì)應(yīng)的值是失效的。
比如走之前是2,關(guān)閉了(或者重新打開時(shí))需要重設(shè)page,當(dāng)前page是1,但是分頁(yè)器組件內(nèi)依舊是2,因此再切換到2分頁(yè)的時(shí)候不會(huì)觸發(fā)事件。
我們可以在監(jiān)聽彈層的is_visible
watch: {
is_visible() {
// 頁(yè)碼為其他關(guān)閉彈層后 再打開彈層應(yīng)當(dāng)將當(dāng)前page設(shè)為1,需要同時(shí)設(shè)置分頁(yè)器內(nèi)的lastEmittedPage為1,否則會(huì)出點(diǎn)了頁(yè)碼沒(méi)反應(yīng)的bug
!this.is_visible && ( this.$refs.elPagition.lastEmittedPage = 1 )
}
},
這樣既可
順便求推薦一波坑少的UI框架