1、話不多說先看效果
主要實現功能:篩選:輸入框、下拉框、時間;表格適用:多選、序號、排序、自定義、開關、鏈接可跳轉、輸入框、圖片、自定義操作按鈕(部分頁面需要每行顯示按鈕不用所以大家按需添加)、常規操作按鈕(每行操作按鈕都相同無其他需求)、設置行背景色、分頁
d8064cea29774f3fbb10fe2a6b59b01c.png
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>