效果!!!
首先工具区
// 工具区
tool: [
// 按钮名称 唯一标识符 权限点 使用element自带按钮类型 自定义背景色
{ name: '新增', permission: '', type: 'success ', bgColor: '', },
{ name: '修改', permission: '', type: 'primary', bgColor: '', },
{ name: '删除', permission: '', type: 'danger', bgColor: '', },
],
数据渲染区
index: true, // 表格 序列 1、2、3 是否开启
selection: true, // 选择
loading: false, // 加载
tableHeight: `calc(100vh - 300px)`, // 高度
data: [], // table数据
//
thead: [
// key: 必填 0-xx
// visible:控制列的显示隐藏 必填
// label:头部标签
// prop:绑定数据属性名
// width:自定义宽度
// align:left/center/right 对齐方式
// isImage: false, 是否开启自定义图片插槽
{ key: 0, visible: true, label: '嘿嘿嘿', prop: 'aa', width: '100', },
],
按钮删除编辑 操作区域
// 表格有操作列时设置
operation: {
isOperation: true, // 是否显示操作
label: '操作', // 列名
width: '200', // 根据实际情况给宽度
fixed: 'right', // 固定到左边还是右边
},
btnList: [ // 功能数组
{
type: 'text', // 按钮类型icon为图表类型
label: '修改', // 功能
icon: 'el-icon-search',
size: 'small', // 按钮大小
plain: false, // 是否设置朴素类型
round: false, // 是否圆角按钮
circle: false, // 是否设置为圆形
permission: '3010105', // 后期这个操作的权限,用来控制权限
},
{
isShowDel: true,
type: 'text', // 按钮类型icon为图表类型
label: '删除', // 功能
icon: 'el-icon-search',
size: 'small', // 按钮大小
plain: false, // 是否设置朴素类型
round: false, // 是否圆角按钮
circle: false, // 是否设置为圆形
permission: '3010105', // 后期这个操作的权限,用来控制权限
}
分页器
// 筛选
queryParams: {
pageSize: 10,
pageNum: 1,
toiletName: '',
status: '',
},
total: 0, // 总条数
以上是配置
下面是组件的封装
<template>
<div class="content">
<!-- 工具区 -->
<el-row justify="space-between" v-if="config.tool.length">
<!-- <div></div> -->
<!-- 有权限后使用 v-permission="item.permission" -->
<div class="tool">
<div class="toolBtn">
<div v-for="item in config.tool" :key="item.name" class="btn">
<template>
<el-button v-bind="item" size="mini" @click="toolBtn(item)">
{{ item.name }}
</el-button>
</template>
</div>
</div>
<div>
<slot></slot>
</div>
</div>
</el-row>
<div class="table">
<el-table :data="config.data" v-loading="config.loading" :height="config.tableHeight"
empty-text="暂无数据" @selection-change="handleSelectionChange">
<el-table-column v-if="config.selection" type="selection" width="55" align="center" />
<!-- 序列 -->
<el-table-column v-if="config.index" type="index" label="序号" />
<template v-for="item in config.thead">
<!-- 自己定义 比如要输入框 显示图片等等 自己定义-->
<el-table-column v-if="item.isImage&& item.visible" :key="item.prop" v-bind="item"
align="center">
<template slot-scope="scope">
<slot :name="item.prop" :scope="scope">
<el-image style="width: 100px; height: 100px" :src="url" :fit="fit"></el-image>
</slot>
</template>
</el-table-column>
<!-- 自己定义 比如要输入框 显示图片等等 自己定义-->
<el-table-column v-if="item.isSwitch&& item.visible" :key="item.prop" v-bind="item"
align="center">
<template slot-scope="scope">
<slot :name="item.prop" :scope="scope">
<el-switch v-model="value" active-color="#13ce66" inactive-color="#ff4949"
active-value="100" inactive-value="0">
</el-switch>
</slot>
</template>
</el-table-column>
<el-table-column v-if="item.isTag&& item.visible" :key="item.prop" v-bind="item">
<template slot-scope="scope">
<slot :name="item.prop" :scope="scope">
<el-tag type="success">标签二</el-tag>
</slot>
</template>
</el-table-column>
<!-- 大部分适用 可直接渲染 自定义的这边需要添加 &&!item.xxxx -->
<el-table-column v-if="!item.isImage && !item.isSwitch && !item.isTag && item.visible"
:key="item.prop" v-bind="item" show-overflow-tooltip align="center" />
</template>
<!-- 操作部分 -->
<el-table-column v-if="config.operation.isOperation" v-bind="config.operation"
align="center">
<template slot-scope="scope">
<template v-for="item, index in config.btnList">
<el-button :key="index" v-bind="item" v-if="!item.isShowDel"
@click.native.prevent="handleRow(scope.$index, scope.row, item.label)">{{ item.label }}</el-button>
<el-popconfirm :key="index" v-if="item.isShowDel" :title="`确认删除吗?`"
@confirm="handleDelete(scope.row)">
<el-button slot="reference" v-bind="item">删除</el-button>
</el-popconfirm>
</template>
</template>
</el-table-column>
</el-table>
</div>
<!--分页区域 v-if="config.total>config.queryParams.pageSize" -->
<div class="pagination">
<el-pagination :current-page.sync="config.queryParams.pageNum" :page-sizes="[10, 20, 30, 50]"
:page-size="config.queryParams.pageSize" layout="total, sizes, prev, pager, next, jumper"
:total="config.total" background @size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</div>
</div>
</template>
<script>
// import { getDelVideoApi } from '@/api/deviceManagement/camera'
export default {
name: 'TableConfig',
props: {
config: {
type: Object,
default: () => { }
}
},
// 监听数据
watch: {
config: {
handler(newVal) {
},
deep: true,
immediate: true
}
},
methods: {
// 删除
handleDelete(val) {
getDelVideoApi(val.id).then((res) => {
if (res.code == 200) {
this.$message.success('删除成功')
if (this.config.queryParams > 1 && this.config.data.length === 1) {
this.config.queryParams-- // 优化 最后页面删除
}
this.$emit('updata')
}
})
},
// 选中的数据
handleSelectionChange(val) {
this.$emit(' handleSelChange', val)
},
// 工具区域按钮
toolBtn(val) {
this.$emit('toolBtn', val)
},
// 操作按钮
handleRow(idx, row, lab) {
this.$emit('handleRow', idx, row, lab)
},
// 换页
handleSizeChange(val) {
this.$emit('changeSize', val)
},
// 换码
handleCurrentChange(val) {
this.$emit('changeNum', val)
}
}
}
</script>
<style lang="less" scoped>
.content {
position: relative;
.tool {
display: flex;
justify-content: space-between;
.toolBtn {
display: flex;
.btn {
margin-right: 10px;
}
}
}
.table {
padding-top: 10px;
}
.pagination {
position: absolute;
margin-top: 10px;
right: 0;
}
}
</style>
所有配置
<template>
<div class="box">
<div>
<el-form v-show="showSearch" ref="queryParams" :model="tableConfig.queryParams" size="small"
:inline="true" label-width="68px">
<el-form-item label="xxx" prop="toiletName">
<el-input v-model="tableConfig.queryParams.toiletName" placeholder="xxx" clearable
style="width: 240px" />
</el-form-item>
<el-form-item label="xxx" prop="status" label-width="100px">
<el-select v-model="tableConfig.queryParams.status" placeholder="xxx" clearable
style="width: 240px">
<el-option label="已绑定" :value="1" />
<el-option label="未绑定" :value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini"
@click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</div>
<TableConfig :config="tableConfig" @changeSize="changeSize" @changeNum="changeNum"
@handleRow="handleRow" @toolBtn="toolBtn" @handleSelChange="handleSelChange"
@updata="resetQuery()">
<template>
<RightToolbar :show-search.sync="showSearch" :columns="tableConfig.thead"
@queryTable="resetQuery" />
</template>
</TableConfig>
<!-- <AddCamera ref="addCamera" @upDataList="resetQuery()" /> -->
</div>
</template>
<script>
// import AddCamera from './components/addCamera' // 添加/修改:弹框
import RightToolbar from '../../components/zwToobar/index'
import TableConfig from '../../components/ZwTable/index.vue'
// 调用接口
// import { getVideoListApi, } from '@/api/deviceManagement/camera'
export default {
name: 'Demo',
components: {
TableConfig, RightToolbar
},
dicts: ['sys_normal_disable'], // 字典使用 v-for="dict in dict.type.sys_common_status"
data() {
return {
showSearch: true, // 控制搜索筛选是否显示
selList: [], // 选中的数组
// table配置
tableConfig: {
// 工具区
tool: [
// 按钮名称 唯一标识符 权限点 使用element自带按钮类型 自定义背景色
{ name: '新增', permission: '', type: 'success ', bgColor: '', },
{ name: '修改', permission: '', type: 'primary', bgColor: '', },
{ name: '删除', permission: '', type: 'danger', bgColor: '', },
],
index: true, // 表格 序列 1、2、3 是否开启
selection: true, // 选择
loading: false, // 加载
tableHeight: `calc(100vh - 300px)`, // 高度
data: [], // table数据
//
thead: [
// key: 必填 0-xx
// visible:控制列的显示隐藏 必填
// label:头部标签
// prop:绑定数据属性名
// width:自定义宽度
// align:left/center/right 对齐方式
// isImage: false, 是否开启自定义图片插槽
{ key: 0, visible: true, label: '嘿嘿嘿', prop: 'aa', width: '100', },
],
// 表格有操作列时设置
operation: {
isOperation: true, // 是否显示操作
label: '操作', // 列名
width: '200', // 根据实际情况给宽度
fixed: 'right', // 固定到左边还是右边
},
btnList: [ // 功能数组
{
type: 'text', // 按钮类型icon为图表类型
label: '修改', // 功能
icon: 'el-icon-search',
size: 'small', // 按钮大小
plain: false, // 是否设置朴素类型
round: false, // 是否圆角按钮
circle: false, // 是否设置为圆形
permission: '3010105', // 后期这个操作的权限,用来控制权限
},
{
isShowDel: true,
type: 'text', // 按钮类型icon为图表类型
label: '删除', // 功能
icon: 'el-icon-search',
size: 'small', // 按钮大小
plain: false, // 是否设置朴素类型
round: false, // 是否圆角按钮
circle: false, // 是否设置为圆形
permission: '3010105', // 后期这个操作的权限,用来控制权限
}
],
// 筛选
queryParams: {
pageSize: 10,
pageNum: 1,
toiletName: '',
status: '',
},
total: 0, // 总条数
},
}
},
created() {
this.getList()
},
methods: {
// 获取列表数据
getList() {
// 测试使用
this.tableConfig.data = [{
aa: 10,
id: 1,
bb: 20
}]
// 获取数据
// getXXXXX(this.tableConfig.queryParams).then((res) => {
// if (res.code == 200) {
// this.tableConfig.data = res.data.list
// this.tableConfig.total = res.data.total
// }
// console.log('resList:', res)
// }).catch((error) => {
// console.error(error)
// }).finally(() => {
// this.tableConfig.loading = false
// })
},
// 操作-按钮事件
handleRow(idx, row, lab) {
if (lab == '修改') {
this.getEdit(row)
}
},
// 工具-按钮 通过判断name 调用不同的方法
toolBtn(val) {
if (val.name == '新增') {
this.getAdd()
}
},
// 新增事件
getAdd() {
this.$refs.addCamera.initData() // 调用弹框的initData方法
},
// 修改事件
getEdit(row) {
this.$refs.addCamera.initData(row)
},
// 选中的数据
handleSelChange(val) {
this.selList = val
},
// 搜索
handleQuery() {
this.tableConfig.queryParams.pageNum = 1
this.getList()
},
// 重置
resetQuery() {
this.$refs.queryParams.resetFields()
this.handleQuery()
},
// 改变每页数量
changeSize(size) {
this.tableConfig.queryParams.pageSize = size
this.getList()
},
// 改变页码
changeNum(pageNum) {
this.tableConfig.queryParams.pageNum = pageNum
this.getList()
},
},
}
</script>
<style lang="less" scoped>
.box {
padding: 20px 30px;
}
</style>
控制数据展示列区域
<template>
<div class="top-right-btn" :style="style">
<el-row>
<el-tooltip v-if="search" class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'"
placement="top">
<el-button size="mini" circle icon="el-icon-search" @click="toggleSearch()" />
</el-tooltip>
<el-tooltip class="item" effect="dark" content="刷新" placement="top">
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
</el-tooltip>
<el-tooltip v-if="columns" class="item" effect="dark" content="显隐列" placement="top">
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" />
</el-tooltip>
</el-row>
<el-dialog :title="title" :visible.sync="open" append-to-body>
<el-transfer v-model="value" :titles="['显示', '隐藏']" :data="columns" @change="dataChange" />
</el-dialog>
</div>
</template>
<script>
export default {
name: 'RightToolbar',
props: {
showSearch: {
type: Boolean,
default: true,
},
columns: {
type: Array,
},
search: {
type: Boolean,
default: true,
},
gutter: {
type: Number,
default: 10,
},
},
data() {
return {
// 显隐数据
value: [],
// 弹出层标题
title: '显示/隐藏',
// 是否显示弹出层
open: false,
}
},
computed: {
style() {
const ret = {}
if (this.gutter) {
ret.marginRight = `${this.gutter / 2}px`
}
return ret
}
},
created() {
// 显隐列初始默认隐藏列
for (const item in this.columns) {
if (this.columns[item].visible === false) {
this.value.push(parseInt(item))
}
}
},
methods: {
// 搜索
toggleSearch() {
this.$emit('update:showSearch', !this.showSearch)
},
// 刷新
refresh() {
this.$emit('queryTable')
},
// 右侧列表元素变化
dataChange(data) {
console.log('data:', data)
for (const item in this.columns) {
const key = this.columns[item].key
this.columns[item].visible = !data.includes(key)
}
},
// 打开显隐列dialog
showColumn() {
this.open = true
},
},
}
</script>
<style lang="less" scoped>
/deep/ .el-transfer__button {
border-radius: 50%;
padding: 12px;
display: block;
margin-left: 0px;
}
/deep/ .el-transfer__button:first-child {
margin-bottom: 10px;
}
</style>
添加/编辑 -- 弹框
<template>
<div>
<!-- 添加或修改参数配置对话框 -->
<el-dialog
:title="form.id ? '修改':'新增'"
:visible.sync="isShow"
width="45%"
append-to-body
@close="onClose"
>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row>
<!-- <el-col :span="12">
<el-form-item label="xxx" prop="deviceName">
<el-input v-model="form.deviceName" placeholder="xxxx" />
</el-form-item>
</el-col> -->
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="isShow=false">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// import { listselectToiletName, } from '@/api/deviceManagement/device'
// import { getAddVideoApi, getEditVideoApi } from '@/api/deviceManagement/camera'
export default {
data() {
return {
isShow: false,
// 表单参数
form: {
toiletId: '',
videoUrlA: '',
videoUrlB: '',
videoUrlC: '',
videoUrlD: '',
deviceSn: ''
},
// 表单校验
rules: {
videoUrlB: [
{ required: true, message: '不能为空', trigger: 'blur' }
],
deviceSn: [
{ required: true, message: '不能为空', trigger: 'blur' }
],
},
}
},
created() {
this.listSelect()
},
methods: {
initData(val = {}) {
this.isShow = true
this.form = val
},
// 提交
async submitForm() {
if (this.form.id) {
await this.$refs.form.validate()
// getEditVideoApi(this.form).then((res) => {
// if (res.code == 200) {
// this.$emit('upDataList')
// this.isShow = false
// } else {
// this.$message.error(res.msg)
// }
// })
} else {
await this.$refs.form.validate()
// getAddVideoApi(this.form).then((res) => {
// if (res.code == 200) {
// this.$emit('upDataList')
// this.isShow = false
// } else {
// this.$message.error(res.msg)
// }
// })
}
},
// 弹框关闭
onClose() {
this.$refs.form.clearValidate()
this.$refs.form.resetFields()
this.isShow = false
},
}
}
</script>
<style lang="scss" scoped>
</style>
更多配置请看