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>