1.组件封装
<template>
<div>
<el-table
ref="multipleTable"
v-loading="loading"
:data="tableData"
border
fit
:row-key="getRowkeys"
@row-click="handleRowClick"
@sort-change="handleSort"
@filter-change="filterHandler"
@selection-change="handleSelectionChange"
>
<!-- 多选框 -->
<el-table-column v-if="selectionShow" :selectable="checkSelectable" type="selection" width="50" align="center" :reserve-selection="true" />
<el-table-column v-if="indexShow" type="index" :index="typeIndex" label="序号" width="50" align="center" />
<el-table-column
v-for="(th, key) in tableHeader"
:key="key"
:prop="th.prop"
:label="th.label"
:fixed="th.fixed"
:sortable="th.custom?'custom':false"
:filters="th.filters"
:column-key="th.columnKey"
:filtered-value="th.filteredValue"
:filter-multiple="th.filterMultiple"
:min-width="th.minWidth || 120"
:width="th.width"
:show-overflow-tooltip="!th.noTooltip"
:class-name="th.className"
:align="th.align || 'center'"
>
<template slot-scope="scope">
<!-- 自定义插槽 -->
<slot v-if="th.type == 'slot'" :name="th.prop" :row="scope.row" />
<!-- 操作按钮 -->
<template v-else-if="th.type == 'button'">
<template v-for="(o, i) in th.operation">
<el-button
v-if="o.isHide ? o.isHide(scope.row) : true"
:key="i"
:type="o.type || 'text'"
@click="o.clickFun(scope.row)"
@mousedown="o.mousedown(scope.row, $event)"
>
{{ o.name }}
</el-button>
</template>
</template>
<!-- 点击跳转页面 -->
<router-link v-else-if="th.type == 'router'" :to="{path: th.path, query: th.query(scope.row)}">
<span
:class="typeof th.itemClassName == 'function'
? th.itemClassName(scope.row) : th.itemClassName"
v-html="handleFilter(th, scope.row, th.prop)"
/>
</router-link>
<!-- 输入框 -->
<el-input
v-else-if="typeof th.type == 'function' ? th.type(scope.row) == 'input': th.type == 'input'"
v-model="scope.row[th.prop]"
@keyup.enter.native="th.change && th.change(scope.row)"
/>
<el-switch
v-else-if="th.type == 'switch'"
v-model="scope.row[th.prop]"
active-color="#13ce66"
inactive-color="#ff4949"
:active-value="1"
:inactive-value="0"
@change="th.handelChange(scope.row, $event)"
/>
<span
v-else
:class="typeof th.itemClassName == 'function' ? th.itemClassName(scope.row) : th.itemClassName"
v-html="handleFilter(th, scope.row, th.prop)"
/>
</template>
</el-table-column>
</el-table>
<div class="pagination" :style="{textAlign:`${pagination_loaction}`}">
<el-pagination
v-if="total > 0"
background
layout="total, prev, pager, next"
class="text-center mt_20"
:current-page="page"
:page-size="limit"
:total="total"
@current-change="handleCurrentChange"
/>
</div>
</div>
</template>
<script>
export default {
name: 'CompTable',
filters: {
formatters (val, format) {
if (typeof (format) === 'function') {
return format(val)
} else return val
}
},
props: {
showRowKey: {
type: Boolean,
default: false
},
tableData: {
type: Array,
default: function () {
return []
}
},
tableHeader: {
type: Array,
default: function () {
return []
}
},
multipleSelection: {
type: Array,
default: function () {
return []
}
},
loading: {
type: Boolean,
default: false
},
selectionShow: {
type: Boolean,
default: false
},
indexShow: {
type: Boolean,
default: false
},
page: {
type: Number,
default: 1
},
limit: {
type: Number,
default: 10
},
total: {
type: Number,
default: 0
},
pagination_loaction: {
type: String,
default: 'right'
}
},
methods: {
// 处理表格序号
typeIndex (index) {
const vm = this // 处理分页数据的 index
return (vm.page - 1) * vm.limit + index + 1
},
// 数据处理
handleFilter (item, val, prop) {
let value = val[prop]
if (item.templet) value = item.templet(val)
return item.filter ? this.$options.filters[item.filter](val[prop]) : value
},
handleSelectionChange (val) {
this.$emit('multiple-Selection', val)
},
handleSort (sort) {
this.$emit('sort-events', sort)
},
filterHandler (filters) {
this.$emit('filter-events', filters)
},
// 当前页改变触发
handleCurrentChange (val) {
this.$emit('current-events', val)
},
handleRowClick (row, column) {
this.$emit('handle-row-click', row, column)
},
checkSelectable (row) {
let isshow = false
if (row.status === 1) {
isshow = false
} else {
isshow = true
}
return isshow
// return !row.status || row.status === 1
},
getRowkeys (row) {
if (this.showRowKey) {
return row.bill_data_id
}
},
// 清空
clearSelection () {
this.$refs.multipleTable.clearSelection()
}
}
}
</script>
<style>
body .el-table th.gutter {
display: table-cell!important;
}
body .pagination {
margin-top: 10px;
}
</style>
2.全局注册
import compTable from '@/components/compTable'
Vue.use(compTable)
3.全局使用
import compTable from '@/components/compTable'
Vue.use(compTable)
4.页面使用
<template>
<div class="wrap">
<el-card class="card-box">
<!--
1.formData:
说明: form 表单绑定的值
类型:Object
案例:
formData: {
name: 1,
}
2.formArr
说明: 文本框的 label
类型:Array
案例:
formArr: [{
type: 'select',
label: '筛选类型',
prop: 'type',
placeholder: '全部',
optionLabelName: 'label',
optionValueName: 'type',
closeClearable: true
}]
3.btnArr
说明: 按钮
类型:Array
案例:
btnArr: [
{ label: '查询', type: 'primary', handle: () => this.handleSearch() }
]
4.inline
说明: 是否是行内表单
类型:Boolean
案例,
:inline='true'
5.formWidth
说明:整个表单的宽度
类型:String
案例,
:formWidth='formWidth', data 中定义 formWidth:200
6.
-->
<fr-form
ref="formData"
form-name="formData"
:form-data="formData"
:form-arr="formArr"
:labelWidth="labelWidth"
:btn-arr="btnArr"
:inline='false'
:rules="formRules"
:formWidth='formWidth'
/>
</el-card>
</div>
</template>
<script>
export default {
data () {
return {
formWidth: '200',
labelWidth: '100px',
size: 'medium',
formData: {
select: '',
input: '',
textarea: '',
number: '',
tel: '',
password: '',
radio: 0,
radioButton: 0,
checkbox: ['北京'],
cascader: '',
date: '',
switch: '',
// img: '',
tinymce: ''
},
btnArr: [
{ label: '确认', type: 'primary', handle: () => this.handleSearch('formData') },
{ label: '重置', type: 'success', handle: () => this.handleReset('formData') },
{ label: '刷新', type: 'plain', handle: () => this.handleFresh() }
],
formArr: [
{
type: 'divider',
title: '标题栏'
},
{ type: 'select',
label: 'select',
prop: 'select',
placeholder: '全部',
optionLabelName: 'label',
optionValueName: 'value',
closeClearable: true,
disabled: () => this.disabled(),
change: () => this.selectChange(),
visibleChange: () => this.visibleChange(),
options: () => this.initSelectValue()
},
{ type: 'input',
label: 'input',
childWidth: '220px',
prop: 'input',
placeholder: '请输入',
handle: () => this.backEnter(),
closeClearable: true
},
{
type: 'textarea',
label: 'textarea',
prop: 'textarea',
childWidth: '420px',
placeholder: '请输入',
optionLabelName: 'label',
maxlength: '10',
closeClearable: true
},
{
type: 'number',
label: 'number',
prop: 'number',
placeholder: '请输入',
childWidth: '420px'
},
{
type: 'tel',
label: 'tel',
prop: 'tel',
placeholder: '请输入',
maxlength: 11,
change: () => this.telChange(),
childWidth: '420px'
},
{
type: 'password',
label: 'password',
prop: 'password',
placeholder: '请输入',
maxlength: 11,
childWidth: '420px'
},
{
type: 'radio',
label: 'radio',
prop: 'radio',
radios: [
{
label: '北京',
value: 0
},
{
label: '上海',
value: 1
},
{
label: '广州',
value: 2
},
{
label: '深证',
value: 3
}
],
change: (e) => this.radioChange(e)
},
{
type: 'radioButton',
label: 'radioButton',
prop: 'radioButton',
radios: [
{
label: '北京',
value: 0
},
{
label: '上海',
value: 1
},
{
label: '广州',
value: 2
},
{
label: '深证',
value: 3
}
],
change: (e) => this.radioButtonChange(e)
},
{
type: 'checkbox',
label: 'checkbox',
prop: 'checkbox',
childWidth: '420px',
change: (e) => this.CheckButtonChange(e),
checkboxs: this.checkBoxList()
},
{
type: 'cascader',
prop: 'cascader',
label: 'Cascader',
placeholder: '请选择',
childWidth: '300px',
options: () => this.CascaderOptions(),
change: () => this.cascaderChange()
},
{
type: 'date',
prop: 'date',
label: 'date',
placeholder: '请选择',
childWidth: '300px'
},
{
type: 'switch',
prop: 'switch',
label: 'switch',
placeholder: '请选择'
},
{
type: 'tinymce',
label: 'tinymce',
prop: 'tinymce',
childWidth: '300px'
}
// {
// type: 'img',
// prop: 'img',
// limit: 1,
// label: 'img',
// remark: '',
// placeholder: '请选择'
// }
],
formRules: {
select: [ { required: true, message: '请选择', trigger: 'change' } ],
input: [ { required: true, message: '请输入', trigger: 'change' } ],
textarea: [ { required: true, message: '请输入', trigger: 'change' } ],
number: [ { required: true, message: '请输入', trigger: 'change' } ],
tel: [ { required: true, message: '请输入', trigger: 'change' } ],
password: [ { required: true, message: '请输入', trigger: 'change' } ],
radio: [ { required: true, message: '请选择', trigger: 'change' } ],
radioButton: [ { required: true, message: '请选择', trigger: 'change' } ],
checkbox: [ { required: true, message: '请选择', trigger: 'change' } ],
cascader: [ { required: true, message: '请选择', trigger: 'change' } ],
date: [ { required: true, message: '请选择', trigger: 'change' } ],
tinymce: [ { required: true, message: '请输入', trigger: 'change' } ],
img: [ { required: true, message: '请选择', trigger: 'change' } ]
},
checkBox: [{
label: '北京',
value: 0
},
{
label: '上海',
value: 1
}]
}
},
methods: {
// 查询
async handleSearch (formData) {
if (await this.$refs.formData.validate(formData)) {
console.log('表单数据', this.formData)
this.$success('验证通过过')
} else {
this.$error('验证失败')
}
},
// 下拉框数据
initSelectValue () {
return [
{ label: '订阅号', value: 'subscribe' },
{ label: '服务号', value: 'server' }
]
},
// 下拉框出现/隐藏时触发,出现则为 true,隐藏则为 false
visibleChange () {
this.$success('下拉框触发')
},
// 下拉框 发生改变
selectChange () {
this.$success('下拉框改变触发')
},
// tel 发生改变
telChange () {
this.$success('手机狂变动输入')
},
// 单选
radioChange (e) {
console.log('单选按钮', e)
this.$success('单选按钮')
},
// 单选按钮
radioButtonChange (e) {
console.log('radioButtonChange', e)
},
// 复选框数据
checkBoxList () {
return [{
label: '北京',
value: 0
},
{
label: '上海',
value: 1
}]
},
// 复选框的值改变
CheckButtonChange (e) {
console.log('复选框的值改变', e)
},
// 级联数据
CascaderOptions () {
return [
{
value: 'zhinan',
label: '指南',
children: [{
value: 'shejiyuanze',
label: '设计原则',
children: [{
value: 'yizhi',
label: '一致'
}, {
value: 'fankui',
label: '反馈'
}, {
value: 'xiaolv',
label: '效率'
}, {
value: 'kekong',
label: '可控'
}]
}, {
value: 'daohang',
label: '导航',
children: [{
value: 'cexiangdaohang',
label: '侧向导航'
}, {
value: 'dingbudaohang',
label: '顶部导航'
}]
}]
}
]
},
// 级联选择器z
cascaderChange (e) {
console.log('级联选择器--cascaderChange', e)
},
// 刷新
handleFresh () {
this.$success('刷新')
/* 强制刷新
this.$router.go(0)
*/
},
// 重置
handleReset (formName) {
this.$refs[formName].resetForm()
this.$success('重置')
},
// 是否重置
disabled () {
return false
},
// 输入框回车键
backEnter () {
this.$success('你点击了 Enter 键')
}
}
}
</script>
<style scoped lang="less">
.wrap{
height: 200px;
}
</style>