前言
vue的UI框架非常多,我司后台主要是用饿了么团队的element ui(http://element.eleme.io/#/zh-CN)开发的,顺便吐槽下之前开发移动端用的是饿了么的mint ui,坑贼多,有空整理下。。。。
业务场景
可以简单理解为一个专场拼接的功能,可以往里面插入各种模块。左边是预览区,右边是控制区(木图帮助大家脑补下emmm),一个模块可以插入很多次,我们这里就当只插入商品模块,商品模块的控制区域(展示商品小图预览然后可以删除),点击+号弹出弹层选择商品。
算了还是上个图吧
弹窗就不放了,element ui 带多选框分页器的demo就是
把这块拆分出来,就是预览区的此模块为父级组件(其上还有预览区为最顶级组件),控制区域为子组件,弹层为子组件调用的模块
关于数据的问题的话可以使用vuex也可以$emit往上一级一级传就不细说了。
DOM结构
<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="项目类型"
prop="product_type"
header-align="center"
width="150"></el-table-column>
<el-table-column
label-class-name="table_header"
label="上架时间"
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>
数据
data() {
return {
is_visible: false, // todo: 弹层是否可以显示
list: [], // 列表数据源
selected: [], // 真实选中的值,用于最后返回
pagination: {
page: 1,
page_size: Number,
total: 1
},
menu1List: [], //筛选相关 三级层连
menu2List: [],
itemList: [],
checkList: [], // 记录之前选中的
title: '', // 搜索后不清空双向绑定的值
tname: '', // 同上,拿来搜索的值
form: {
item_id: '',
menu1_id: '',
menu2_id: '',
}
}
},
功能梳理
1、表格经过搜索、分页后,数据保留
table绑定的selection-change只能拿到当前表格选中的值,因此要设置两个数组。每次触发selection-change将当前结果放入selected,当list重新刷新之前,处理checkList
this.checkList = this.unique( this.checkList.concat( this.selected ) )
unique( arr ) {
// 带有getset的对象似乎不能用es6数组去重
// 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、自动勾选
很显然我们这个需求是可以选中已有模块,此时弹窗时数据应同步到table中并选中相应元素。其次在换页、重新搜索时,也应把checkList内的值重新选中。
因为实在没找着column api里有关于默认勾选的设置,或许是我眼瞎,求指正。。。 就只能在页面组件load、list刷新时手动勾选。
//其他组件可以通过调用此ref的load()来调出
load( ...rest ) {
...//通过参数传好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模块只存在一个,因此每次load的时候都需要重置搜索条件、page。但是手动修改data里面的current-page对应的值是失效的。
比如走之前是2,关闭了(或者重新打开时)需要重设page,当前page是1,但是分页器组件内依旧是2,因此再切换到2分页的时候不会触发事件。
我们可以在监听弹层的is_visible
watch: {
is_visible() {
// 页码为其他关闭弹层后 再打开弹层应当将当前page设为1,需要同时设置分页器内的lastEmittedPage为1,否则会出点了页码没反应的bug
!this.is_visible && ( this.$refs.elPagition.lastEmittedPage = 1 )
}
},
这样既可
顺便求推荐一波坑少的UI框架