table组件的封装
<!--
代码结构:
data:
1.pagingList -- table 数据
2.hasSelect -- 是否开启第一行的选择框
3.selectWidth -- 定义选择框大小 只支持数字
4.option -- 整个表格的配置项 例子格式如下:
4.1 opition 对象中的opition字段是用来配置table列规则参考ele 即可 其中自定义一个hasColumn用来增加这个表格是否可以点击
4.2 button 用来配置table 最后一列是否是按钮形式显示
4.3 popoverLiList 适用于本项目的下拉菜单,如果是下拉菜单请直接配置这个选项
4.4 buttonContent 需要自己定义不适用本项目的通用下拉配置这个项
4.4.1 parentFun 回调方法 根据定义名称在子组件使用即可
4.4.2 title 配置文字按钮
4.4.3 icon 配置图标直接放入图标的class
{
opition:[
{prop:'name',label:'姓名',width:320},
{prop:'date',label:'日期',width:320},
{prop:'address',label:'地址',hasColumn:true,width:120},
],
button:{hasButton:true,label:'操作',fixed:'right',},
// popoverLiList:[
// {parentFun:'handleResetPwd',title:'重置密码'},
// {parentFun:'handleEdit',title:'编辑'},
// {parentFun:'handlePermission',title:'设置权限'},
// {parentFun:'handleDisable',title:'停用'},
// ],
buttonContent:[
{parentFun:'handleResetPwd',icon:'icon-sousuo'},
{parentFun:'handleEdit',title:'编辑'},
{parentFun:'handlePermission',title:'设置权限'},
{parentFun:'handleDisable',title:'停用'},
],
}
样式:
1.tableRowClassName -- table行的样式
2.tableTheadClassName -- 头部样式
3.tableTheadClassName -- 头部标题样式
方法:
1.multipleTable -- ref 对外暴露的组件,可以在父组件中直接使用这个ref 获取组件中所有内容
2.handleSelectionChange -- 选择框如果在父组件使用这个选择框,需要在父组件定义handleSelect 这个方法,用数组来接收每一个选择内容
3.handleDetailRow 当设置 hasColumn 使用使用handleDetailRow 回调给父组件的方法
4.handleParentFun 对自定义的一些按钮配置方法给会父组件
-->
<template>
<div class="customized-table">
<el-table v-bind:data="pagingList" border v-bind:row-class-name="tableRowClassName" v-on:selection-change="handleSelectionChange"
v-bind:header-cell-class-name="tableTheadClassName" style="width: 100%" ref="multipleTable">
<!--是否有选择框-->
<el-table-column
v-if="hasSelect"
type="selection"
:width="selectWidth">
</el-table-column>
<!--只展示不可点击-->
<el-table-column
v-for="(item,index) in option.opition"
v-if="!item.hasColumn"
:prop="item.prop"
:label="item.label"
:width="item.width"
:sortable="item.sort"
:formatter="item.formatter"
:fixed='item.fixed'
:resizable="item.resizable||false"
:key="index">
</el-table-column>
<!--展示可以点击-->
<el-table-column
v-else
:prop="item.prop"
:label="item.label"
:width="item.width"
:sortable="item.sort"
:formatter="item.formatter"
:fixed='item.fixed'
:resizable="item.resizable||false"
:key="index">
<template slot-scope="scope">
<a class="cursor-pointer" @click.prevent="handleDetailRow(scope.row)">{{ scope.row[item.prop] }}</a>
</template>
</el-table-column>
<el-table-column
v-if="option.button.hasButton"
:label="option.button.label"
:fixed="option.button.fixed">
<template slot-scope="scope">
<!--自定义按钮-->
<ul class="buttonContent" v-if="option.buttonContent">
<li v-for="item in option.buttonContent" >
<a v-if="item.icon" @click="handleParentFun(scope.row,item.parentFun)" href="javascript:;" >
<i :class="['iconfont',item.icon]"></i>
</a>
<a v-else @click="handleParentFun(scope.row,item.parentFun)" href="javascript:;" >
{{item.title}}
</a>
</li>
</ul>
<!--项目下拉按钮-->
<el-popover v-else
placement="bottom"
:width="option.button.width||160"
trigger="hover"
:popper-class="option.button.popperClass||'tMoreEdit'">
<ul>
<li v-for="item in option.popoverLiList">
<a @click="handleParentFun(scope.row,item.parentFun)" href="javascript:;" >{{item.title}}</a>
</li>
</ul>
<a class="iconfont icon-gengduo" slot="reference"></a>
</el-popover>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "CustomizedTable",
props:{
pagingList:{
type:Array,
},
selectWidth:{
type:Number,
default:55,
},
hasSelect:{
type:Boolean,
default:true,
},
option:{
type:Object,
required:true,
},
},
methods:{
tableRowClassName (row) {return 'cyTatble-row';},
tableTheadClassName(){return "cyTable-thead"; },
handleSelectionChange(val){
this.$emit('handleSelect',val);
},
handleDetailRow(val){
this.$emit('handleDetailRow',val);
},
handleParentFun(val,parentFun){
this.$emit(parentFun,val);
}
}
}
</script>
<style lang="less">
.customized-table{
border-right: 1px solid #ebeef5;
.tMoreEdit.el-popover{padding:0;}
.tMoreEdit[x-placement^=bottom] {margin-top: 0px !important;}
.tMoreEdit li{height:40px;}
.tMoreEdit li:hover{background-color: #F2F4F7;}
.tMoreEdit li>a{display: block;line-height: 40px;border-bottom: 1px solid #f2f4f7;margin: 0 10px;color: black;}
.tMoreEdit li:last-child a{border-bottom:none;}
.cursor-pointer{cursor:pointer ;}
.el-table {
.cyTable-thead{
background-color:#fafafa;color:#000;border:none;
.cyTable-evenRow {background-color:#f5f7fb; border:none;color:#000}/*偶数行颜色*/
.cytatble-row{color:#000;}
.cytatble-row.userStatus-false {color:#999999;}
}
}
.el-table--border td, .el-table--border th, .el-table__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed {
border-right: none !important;
}
a.icon-gengduo{
cursor: pointer;
color: #337ab7;
transform:rotate(90deg);
}
a.icon-gengduo:hover{
color:#576B95;
}
.buttonContent{
li{
float: left;
margin-right: 10px;
>a{
color:#576B95!important;
}
}
li:last-child{
margin-right: 0;
}
}
}
</style>
input 搜索的封装
<template>
<div class="input-search">
<input class="input input-clear" :value="value" @input="$emit('input', $event.target.value)" :placeholder="placeholder" @keyup.enter="handleSearch"/>
<div class="input input-icon" v-on:click="handleSearch" >
<slot v-if="$slots.icon"></slot>
<i class="iconfont icon-sousuo" v-else></i>
</div>
</div>
</template>
<script>
import {extend} from '@/lib/tools'
export default {
name: "Search",
props:{
value:{
type:String,
},
placeholder:{
type:String,
},
backEndSearch:{
type:Boolean,
default:false,
},
tableData:{
type:Array,
},
opitionSearchItem:{
type:Array,
required:true,
},
},
data(){
return{
}
},
methods:{
handleSearch(){
if(this.backEndSearch){
this.$emit('backEndSearch',value);
}else{
let searchData = [];
if (this.value === ''){
extend(this.tableData,searchData )
} else{
let _this = this;
let str = '';
this.opitionSearchItem.forEach((ele, index)=>{
str += `ele.${ele}===_this.value||` ;
});
str = str.substr(0,str.length-2);
searchData = this.tableData.filter((ele)=>{
if(eval(str)){
return ele
}
})
}
this.$emit('handleSreach',searchData);
};
},
}
}
</script>
<style scoped lang="less">
.input-search{
width: 100%;
height: 100%;
border: 1px solid #E2E2E2;
/*height: 32px;*/
box-sizing: border-box;
padding: 6px 12px;
font-size: 16px;
border-radius:3px;
background-color: #FFFFFF;
/*position: relative;*/
.input{
/*position: absolute;*/
line-height: 20px;
/*top:0;*/
&-clear{
float: left;
border: none;
outline: none;
}
&-icon{
border-left: 1px solid #E2E2E2;
float: right;
color:#B9C0CB;
padding-left: 10px;
}
}
}
</style>