共计 12841 个字符,预计需要花费 33 分钟才能阅读完成。
1、话不多说先看成果
次要实现性能:筛选:输入框、下拉框、工夫;表格实用:多选、序号、排序、自定义、开关、链接可跳转、输入框、图片、自定义操作按钮(局部页面须要每行显示按钮不必所以大家按需增加)、惯例操作按钮(每行操作按钮都雷同无其余需要)、设置行背景色、分页
2、本文局部原创,大框架是复制的 https://blog.csdn.net/qq_37346639/article/details/115556605 这个博客,因为懒的本人写😂,依照需要改为本人所须要格局
3、筛选组件代码
<template>
<div>
<ul class="row-list" v-if="screenConfig.searchShow">
<li v-for="(item,index) in screenConfig.formItem" :key="index">
<label v-if="item.type !='operationBtn'">{{item.label}}:</label>
<!-- 输入框 -->
<el-input v-if="item.type ==='input'"clearable v-model.trim="screenConfig.searchParams[item.prop]"class="w215"size="small":placeholder="item.placeholder"></el-input>
<!-- 下拉框 -->
<el-select v-if="item.type ==='select'"filterable clearable v-model.trim="screenConfig.searchParams[item.prop]":placeholder="item.placeholder"size="small":multiple="item.multiple":filterable="item.filterable">
<el-option v-for="selectItem in item.options" :key="selectItem[item.value]" :value="selectItem[item.value]"
:label="selectItem[item.leftLabel]" :disabled="selectItem.disabled">
<span style="float: left">{{selectItem[item.leftLabel] }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{selectItem[item.rightLabel] }}</span>
</el-option>
</el-select>
<!-- 工夫选择器 -->
<el-date-picker v-if="item.type ==='datePicker'"clearable v-model="screenConfig.searchParams[item.prop]":type="item.dateType"size="small":value-format="item.format"placeholder=" 请抉择 "range-separator=" 至 "start-placeholder=" 开始日期 "end-placeholder=" 完结日期 ">
</el-date-picker>
<!-- 自定义 -->
<slot v-if="item.type =='custom'"name='customFilter'></slot>
<!-- 按钮 -->
<span v-if="item.type =='operationBtn'"v-for="(operations, index) in item.operation":key="index">
<el-button v-if="operations.isShow" :type="operations.btnType" :icon="`iconfont ${operations.icon}`"
@click="screenBtn(operations)" class="screen-btn" :disabled="operations.disabled"
size="mini">{{operations.label}}
</el-button>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "PublicFilter",
props: {
screenConfig: {
type: Object,
required: true
},
},
data() {return {};
},
methods: {
// 操作按钮
screenBtn(data) {this.$emit("screenBtn",data)
}
},
}
</script>
<style scoped lang="less">
.screen-btn {margin-right: 10px;}
.row-list {
li{
margin-bottom: 15px;
float: left;
margin-right: 15px;
min-height: 32px;
line-height: 32px;
}
}
</style>
4、表格组件代码
<template>
<div>
<el-table size="medium" :data="tableData" :stripe="false" :border="false" :fit="true"
:header-cell-style="{background:columnObj.headerBgColor,color: columnObj.headerColor,height: columnObj.headerHigh}"
:highlight-current-row="columnObj.highlight" :row-class-name="tableRowClassName"
@row-click="rowClick" :row-style="tableRowStyle" @sort-change="sortChange">
<!-- 抉择框是否开启,selectable 管制是否单行禁用 -->
<el-table-column v-if="columnObj.selection" type="selection" :selectable="selectable" :align="columnObj.align ||'center'"></el-table-column>
<el-table-column v-if="columnObj.serialNumber" type="index" label="序号" :align="columnObj.align ||'center'"width="50"></el-table-column>
<!-- 一般列 -->
<el-table-column v-for="(column,columIndex) in columnObj.columnData" :key="columIndex" :prop="column.prop"
:label="column.label" :width="column.width" :fixed="column.fixed" :align="columnObj.align ||'center'":sortable="column.sortable":index="columIndex" show-overflow-tooltip>
<template slot-scope="{row,$index}">
<!-- 默认展现 -->
<span v-if="column.type =='text'":style="{color:row[column.colorName]}">
{{row[column.prop]}}
</span>
<!-- 标签类型 -->
<span v-if="column.type =='tag'">
<el-tag :type="row[column.tagType]">{{row[column.prop]}}</el-tag>
</span>
<!-- 自定义内容 -->
<slot v-if="column.type =='ownDefined'"name='ownDefined':row="row,column"></slot>
<!-- switch 开关 -->
<el-switch v-if="column.type =='switch'"v-model="row[column.prop]":inactive-text="row[column.prop] ? column.openText:column.closeText"@change="switchChange(row,$index,column.prop)"></el-switch>
<!-- 图片展现 -->
<el-image v-if="column.type =='image'"style="width: 50px; height: 50px":src="row[column.prop]"fit="cover":preview-src-list="[row[column.prop]]"></el-image>
<!-- url-->
<div v-if="column.type =='url'">
<a v-if="row[column.urlName]" :href="row[column.urlName]" target="_blank" class="url">{{row[column.prop]}}</a>
<span v-else>{{row[column.prop]}}</span>
</div>
<!-- 可编辑 -->
<el-input v-if="column.type =='editRow'"v-model="row[column.prop]":disabled="row[column.editRow]"@blur="editInputBlur(row,$index,column.prop,columIndex)"size="mini"></el-input>
<!-- 自定义操作按钮,每行不一样 -->
<span v-if="column.type =='customAction'"v-for="(operations, index) in row[column.prop]":key="index">
<el-button v-if="operations.isShow" type="text"
@click="rowOperation(row,$index,operations.type)" :style="{color:operations.color}"
size="small">{{operations.label}}
</el-button>
</span>
<!-- 惯例操作按钮 -->
<span v-if="column.type =='routineAction'"v-for="(operations, index) in column.operation":key="index">
<el-button v-if="operations.isShow" type="text"
@click="rowOperation(row,$index,operations.type)" :style="{color:operations.color}"
size="small">{{operations.label}}
</el-button>
</span>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="page_div" :style="{textAlign: pageObj.position ||'center'}" v-if="pageObj.show">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:hide-on-single-page="false" :current-page="pageObj.pageNo" :pager-count="7"
:page-sizes="[10, 15, 20, 30,50]" :page-size="pageObj.pageSize" background
layout="total,sizes,prev, pager, next" :total="pageObj.total">
</el-pagination>
</div>
</div>
</template>
<script>
export default {
name: 'public-table',
props: {
tableData: {
type: Array,
required: true
},
columnObj: {
type: Object,
required: true
},
pageObj: {
type: Object,
required: true
}
},
data() {return {}
},
methods: {
// 管制单行是否可用
selectable(row, index) {if (row.switchs) {return true;}
this.$emit("selectable", row, index)
},
// 操作按钮
rowOperation(row, $index, now) {this.$emit("rowOperation", row, $index, now)
},
// switchChange 调用
switchChange(row, $index, prop) {this.$emit("switchChange", row, $index, prop);
},
// 行款式
tableRowStyle({row}) {if(row.styleData) {return {'background': `${row.styleData.bgColor}`,'color':`${row.styleData.fontColor}`};
}
},
// 行的 className 的回调办法
tableRowClassName({row, rowIndex}) {row.rowIndex = rowIndex;},
// 点击行
rowClick(row, column, event) {this.$emit("rowClick", row, column, event);
},
// 可编辑 input 失去焦点
editInputBlur(row, $index, prop, columIndex) {this.$emit('editInputBlur', row, $index, prop, columIndex);
},
// 近程排序
sortChange({column, prop, order}) {
// ascending 上 descending 下
this.$emit('sortChange', column, prop, order);
},
// 条数变动
handleSizeChange(e) {this.$emit('handleSizeChange', e);
},
// 页码变动
handleCurrentChange(e) {this.$emit('handleCurrentChange', e);
}
}
}
</script>
<style lang="less" scoped>
.el-button {margin: 0 6px;}
.page_div {padding: 15px 0;}
.url {
color: #3d8de0;
cursor: pointer;
}
/deep/.el-table__body tr.current-row>td.el-table__cell {background-color: #a8b9cc;}
/deep/.el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {color: #606266;}
</style>
5、全局引入组件
**main.js** 页面全局引入组件或单页面引入看需要,我是全局引入
import {PublicTable,PublicFilter} from '@/components';
Vue.component(PublicTable.name,PublicTable);
Vue.component(PublicFilter.name,PublicFilter);
文件目类
[图片上传失败 …(image-70848a-1662602567621)]
components>index.js
import PublicTable from '@/components/PublicTable';
import PublicFilter from '@/components/PublicFilter';
export {PublicTable,PublicFilter};
6、父组件应用
<template>
<div class="box">
<el-card shadow="never">
<public-filter :screenConfig="screenConfig" @screenBtn="screenBtn">
<template slot='customFilter'>
<el-radio-group v-model="screenConfig.searchParams.aaa" class="radio">
<el-radio :label="3"> 备选项 </el-radio>
<el-radio :label="6"> 备选项 </el-radio>
<el-radio :label="9"> 备选项 </el-radio>
</el-radio-group>
</template>
</public-filter>
</el-card>
<el-card shadow="never" class="mt-20">
<public-table :tableData="tableData" :columnObj="columnObj" :pageObj="pageObj" @rowOperation="rowOperation"
@switchChange="switchChange" @editInputBlur="editInputBlur" @rowClick="rowClick"
@sortChange="sortChange"
@handleSizeChange="handleSizeChange" @handleCurrentChange="handleCurrentChange">
<template slot='ownDefined' slot-scope="{row,column}">
<p>
<span v-if="row.names" :class="`iconfont ${row.names.icon}`" :style="{fontSize: row.names.fontSize,color: row.names.color}"></span>
{{row.name}}
</p>
<p>{{row.address}}</p>
</template>
</public-table>
</el-card>
</div>
</template>
<script>
export default {data() {
return {
// 筛选配置
screenConfig:{
searchShow: true, // 筛选是否显示
formItem: [{
type: "input",
prop:'input',
label: "姓名",
placeholder:'请输出姓名'
}, {
type: "select",
prop: "parkingType",
label: "类型",
value:"id",
leftLabel:"name",
rightLabel:"gender",
multiple: false,
filterable: true,
options: [{
id: '1',
name: '张三',
gender: '男',
},{
id: '2',
name: '李四',
disabled: true
},{
id: '3',
name: '李四',
gender: '女',
}],
placeholder:'请抉择数据'
}, {
type: "datePicker",
prop: "data",
label: "导出工夫",
format: "yyyy-MM-dd", // 数据格式 'yyyy-MM-dd'、timestamp(工夫戳)dateType: "datetimerange", // 显示类型(罕用类型 daterange、date、datetime)year 年、month 月、date 日期、dates 多个日期、week 周、datetime 日期和工夫点、datetimerange 日期和工夫范畴、daterange 日期范畴、monthrange 月份范畴
placeholder: '请抉择',
}, {
type: "custom",
prop: "aaa",
label: "自定义筛选",
}, {
type: "operationBtn",
prop: "data",
operation: [{
btnType: "primary", //primary 蓝色、success 绿色、warning 橘黄、danger 红色、info 灰色、text 文本
type: 'cx',
label: "查问",
isShow: true,
disabled: false,
icon: 'icon-cry',
},{
btnType: "danger", //primary 蓝色、success 绿色、warning 灰色、danger 橘黄、info 红色、text 文本
type: 'cz',
label: "重置",
isShow: true,
disabled: true,
icon:'icon-atm-away'
}]
}]
},
// 表头配置
columnObj: {
selection: true,// 抉择框
serialNumber: true,// 序号
highlight: false,// 以后行是否高亮
align: 'center',// 对齐形式
headerBgColor: '',// 表头背景色
headerColor: '',// 表头字体色彩
headerHigh: '55px',// 表头高
// columnObj
// selection(是否有多选框):true 显示,false 暗藏
// serialNumber(是否有序列号):true 显示,false 暗藏
// align(行文字对其形式):left 左,right 右,center 居中
// highlight(以后行是否高亮)
// headerColor(表头字体色彩)
// headerHigh(表头高): 小于 55px 没有成果
// columnObj>columnData
//type(列类型):text 文本,ownDefined 自定义,switch 开关,url 链接,editRow 可编辑,image 图片,customAction 自定义操作,routineAction 惯例操作
//prop(参数),label(列名),width(宽度)
//sortable(是否反对排序):true 开启排序,false 敞开排序 'custom' 近程排序
//openText,closeText(开关开启 / 敞开名称),urlName(url 地址对应参数):参数为空时只展现文字不可跳转
//editRow(以后行是否可编辑和 type 为 editRow 对应):false 可编辑,true 不可编辑
//colorName 管制文字色彩字段名
columnData: [{
type:'text',
prop: "school",
label: "默认款式",
width: "",
colorName: "color",
}, {
type:'tag',
prop: "tag",
tagType: "tagType",
label: "标签类型",
width: "",
}, {
type:'text',
prop: "id",
label: "能够排序",
width: "",
sortable: true,
}, {
type:'ownDefined',
prop: "aaa",
label: "自定义内容",
width: "",
}, {
type:'switch',
prop: "switchs",
label: "switch 开关",
width: "",
openText: "关上", //type='switch' 关上时的文字描述
closeText: "敞开", //type='switch' 敞开时的文字描述
}, {
type:'url',
prop: "name2",
label: "可跳转",
urlName: "url", //type='url', 跳转地址名称(按需返回)width: "",
}, {
type:'editRow',
prop: "name",
label: "可编辑",
width: "",
editRow: 'editRow',
},{
type:'image',
prop: "img",
label: "图片",
width: "",
}, {
type:'customAction',
label: "自定义操作",
width: "180",
prop: "operation",
}, {
type:'routineAction',
label: "惯例操作",
width: "180",
operation: [{
type: "cg",
label: "惯例",
color: '',
isShow: true,
}]
}],
},
// 表格数据
// editRow(可编辑行是否可操作 true/false)
// styleData(Object 类型,行款式, 背景色、字体色彩等)
//operation(Array 类型,表头 type=‘customAction’时按钮配置):type 类型,label 按钮名,color 按钮色彩,isShow 是否显示(true/false),// tagType 标签类型(success 绿 /info 灰 /warning 橘黄 /danger 红 /)返回空为默认值蓝色
tableData: [{
id: '1',
school: '北京大学',
name: '王小虎',
tag: '标签一',
tagType: 'success',
names:{
name: '王小虎',
icon:'icon-phone',
fontSize: '15px',
color:"red",
},
editRow: true,
address: '上海市普陀区金沙江路 1518 弄',
switchs: true,
img: '',
name2: '张三',
icon: 'icon-phone',
// 行款式
styleData: {
bgColor: '#878787',
fontColor: '#fff',
},
operation: [{
type: "edit",
label: "编辑",
color: '#be147d',
isShow: true,
}, {
type: "delete",
label: "删除",
color: 'red',
isShow: false,
}, {
type: "see",
label: "查看",
color: '#d77000',
isShow: true,
}],
}, {
id: '2',
school: '天津大学',
name: '王小虎',
tag: '标签二',
tagType: '',
names:{
name: '王小虎 2',
icon:'icon-cry',
fontSize: '18px',
color:"blue",
},
address: '上海市普陀区金沙江路 1517 弄',
switchs: true,
img: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
name2: '李四',
url:'https://www.baidu.com/',
}, {
id: '3',
school: '北京体育',
tag: '标签三',
tagType: 'info',
color: 'red',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄',
switchs: false,
name2: '王五',
img: '',
operation: [{
type: "edit",
label: "编辑",
color: '#67C23A',
isShow: true,
}, {
type: "delete",
label: "删除",
color: 'red',
isShow: true,
}, {
type: "see",
label: "查看",
color: '',
isShow: true,
}]
}, {
id: '4',
school: '河北师范大学',
name: '王小虎',
tag: '标签四',
tagType: 'warning',
address: '上海市普陀区金沙江路 1516 弄',
switchs: true,
name2: '赵六',
url:'https://www.baidu.com/',
img: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
}],
// 分页配置
pageObj: {
show: true, // 是否显示
position: "right", // 地位
total: 100,
pageNo: 1,
pageSize: 10
},
}
},
created(){this.$set(this.screenConfig,'searchParams',{})
},
methods: {screenBtn(data) { },
rowOperation(row, $index, now) {console.log(row, $index, now)
},
switchChange(row, $index, prop) {console.log(row, $index, prop)
},
rowClick(row, column, event) {
// 点击行触发,编辑点击的所在列,排除 selection 抉择框
// if (column.type != 'selection') {// this.columnObj.columnData[column.index].editRow = row.rowIndex;
// }
},
sortChange(column, prop, order) {// console.log(column, prop, order)
},
editInputBlur(row, $index, prop, columIndex) {// console.log(row, $index, prop, columIndex)
// this.columnObj.columnData[columIndex].editRow = -1;
},
// 页码变动
handleCurrentChange(e) {this.pageObj.pageNo = e;},
// 条数变动
handleSizeChange(e) {
this.pageObj.pageSize = e;
this.pageObj.pageNo = 1;
},
},
}
</script>
<style>
.box {
background: #f4f4f4;
padding: 2% 1%;
box-sizing: border-box;
}
</style>
正文完