老样子,先来个效果图
查询表单数据和表格的列信息以及表格数据都是从后端拿到后自动渲染成下面的格式,
一、先创建表格和表单组件
下面的form和table组件,可以直接复制使用的,如果你需要!
form.vue
<template>
<div class="ces-search">
<el-form class="form" ref="refForm" :size="size" inline :label-width="labelWidth">
<el-form-item v-for='item in searchForm' :label="item.label" :key='item.prop' class="formItem">
<!-- 输入框 -->
<el-input v-if="item.type==='Input'" v-model="searchData[item.prop]" size="mini" :style="{width:item.width}"></el-input>
<!-- 下拉框 -->
<el-select v-if="item.type==='Select'" v-model="searchData[item.prop]" size="mini" @change="item.change(searchData[item.prop])" :style="{width:item.width}">
<el-option v-for="op in item.options" :label="op.label" :value="op.value" :key="op.value"></el-option>
</el-select>
<!-- 单选 -->
<el-radio-group v-if="item.type==='Radio'" v-model="searchData[item.prop]">
<el-radio v-for="ra in item.radios" :label="ra.value" :key="ra.value">{{ra.label}}</el-radio>
</el-radio-group>
<!-- 单选按钮 -->
<el-radio-group v-if="item.type==='RadioButton'" v-model="searchData[item.prop]" @change="item.change && item.change(searchData[item.prop])">
<el-radio-button v-for="ra in item.radios" :label="ra.value" :key="ra.value">{{ra.label}}</el-radio-button>
</el-radio-group>
<!-- 复选框 -->
<el-checkbox-group v-if="item.type==='Checkbox'" v-model="searchData[item.prop]" >
<el-checkbox v-for="ch in item.checkboxs" :label="ch.value" :key="ch.value">{{ch.label}}</el-checkbox>
</el-checkbox-group>
<!-- 日期 -->
<el-date-picker v-if="item.type==='Date'" v-model="searchData[item.prop]" ></el-date-picker>
<!-- 时间 -->
<el-time-select v-if="item.type==='Time'" v-model="searchData[item.prop]" type=''></el-time-select>
<!-- 日期时间 -->
<el-date-picker v-if="item.type==='DateTime'" type='datetime' v-model="searchData[item.prop]" :disabled="item.disable && item.disable(searchData[item.prop])"></el-date-picker>
<!-- 日期范围 -->
<el-date-picker v-if="item.type==='datetimerange'" type='datetimerange' v-model="searchData[item.prop]" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
<!-- 滑块 -->
<!-- <el-slider v-if="item.type==='Slider'" v-model="searchData[item.prop]"></el-slider> -->
<!-- 开关 -->
<el-switch v-if="item.type==='Switch'" v-model="searchData[item.prop]" ></el-switch>
</el-form-item>
</el-form>
<el-form class="formT" inline v-if='isHandle'>
<el-form-item v-for='(item , index) in searchHandle' :key="index">
<el-button :type="item.type" :size="item.size || size" @click='item.handle()'>{{item.label}}</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
props:{
isHandle:{
type:Boolean,
default:true
},
labelWidth:{
type:String,
default:'50px'
},
size:{
type:String,
default:'mini'
},
searchForm:{
type:Array,
default:[]
},
searchHandle:{
type:Array,
default:()=>[]
},
searchData:{
type:Object,
default:{}
}
},
data () {
return {
};
},
methods:{
}
}
</script>
<style lang="scss" >
.ces-search{
display: flex;
justify-content: space-between;
.formItem{
.el-form-item__label{
width: 80px !important;
}
}
}
</style>
table.vue
<!--表格组件 -->
<template>
<section class="ces-table-page">
<!-- 表格操作按钮 -->
<section class="ces-handle" v-if='isHandle'>
<el-button v-for='(item , index) in tableHandles' :size="item.size || size" :type="item.type" :icon='item.icon' @click="item.handle()" :key="index">{{item.label}}</el-button>
</section>
<!-- 数据表格 -->
<section class="ces-table">
<el-table
:data='tableData'
:size='size'
:border ='isBorder'
@select='select'
@select-all='selectAll'
v-loading='loading'
header-row-class-name="header_row_style"
:defaultSelections='defaultSelections'
ref="cesTable">
<el-table-column v-if="isSelection" type="selection" align="center" width="50" ></el-table-column>
<el-table-column v-if="isIndex" type="index" :label="indexLabel" align="center" width="50"></el-table-column>
<!-- 数据栏 -->
<el-table-column v-for="item in tableCols"
:key="item.id"
:prop="item.prop"
:label="item.label"
:width="item.width"
:align="item.align"
show-overflow-tooltip
:render-header="item.require?renderHeader:null"
>
<template slot-scope="scope" >
<!-- html -->
<span v-if="item.type==='Html'" v-html="item.html(scope.row)"></span>
<!-- 按钮 -->
<span v-if="item.type==='Button'" >
<el-button v-for="(btn , index) in item.btnList"
:disabled="btn.isDisabled && btn.isDisabled(scope.row)"
:type="btn.type"
:size="btn.size || size"
:icon="btn.icon"
:key="index"
@click="btn.handle(scope.row)">{{btn.label}}</el-button>
</span>
<!-- 输入框 -->
<el-input v-if="item.type==='Input'" v-model="scope.row[item.prop]" :size="size"
:disabled="btn.isDisabled && btn.isDisabled(scope.row)"
@focus="item.focus && item.focus(scope.row)"></el-input>
<!-- 下拉框 -->
<el-select v-if="item.type==='Select'" v-model="scope.row[item.prop]" :size="size" :props="item.props"
:disabled="btn.isDisabled && btn.isDisabled(scope.row)"
@change='item.change && item.change(scope.row)'>
<el-option v-for="op in item.options" :label="op[item.props.label]" :value="op[item.props.value]" :key="op[item.props.value]"></el-option>
</el-select>
<!-- 单选 -->
<el-radio-group v-if="item.type==='Radio'" v-model="scope.row[item.prop]"
:disabled="btn.isDisabled && btn.isDisabled(scope.row)"
@change='item.change && item.change(scope.row)'>
<el-radio v-for="(ra , index) in item.radios" :label="ra.value" :key="index">{{ra.label}}</el-radio>
</el-radio-group>
<!-- 复选框 -->
<el-checkbox-group v-if="item.type==='Checkbox'" v-model="scope.row[item.prop]"
:disabled="btn.isDisabled && btn.isDisabled(scope.row)"
@change='item.change && item.change(scope.row)'>
<el-checkbox v-for="(ra ,index) in item.checkboxs" :label="ra.value" :key="index">{{ra.label}}</el-checkbox>
</el-checkbox-group>
<!-- 评价 -->
<el-rate v-if="item.type==='Rate'" v-model="scope.row[item.prop]"
:disabled="btn.isDisabled && btn.isDisabled(scope.row)"
@change='item.change && item.change(scope.row)'></el-rate>
<!-- 开关 -->
<el-switch v-if="item.type==='Switch'" v-model="scope.row[item.prop]"
:disabled="btn.isDisabled && btn.isDisabled(scope.row)"
@change='item.change && item.change(scope.row)'></el-switch>
<!-- 图像 -->
<img v-if="item.type==='Image'" :src="scope.row[item.prop]" @click="item.handle && item.handle(scope.row)"/>
<!-- 滑块 -->
<el-slider v-if="item.type==='Slider'" v-model="scope.row[item.prop]"
:disabled="btn.isDisabled && btn.isDisabled(scope.row)"
@change='item.change && item.change(scope.row)'></el-slider>
<!-- 默认 -->
<span v-if="!item.type"
:style="item.itemStyle && item.itemStyle(scope.row)"
:class="item.itemClass && item.item.itemClass(scope.row)">{{(item.formatter && item.formatter(scope.row)) || scope.row[item.prop]}}</span>
</template>
</el-table-column>
</el-table>
</section>
<!-- 分页 -->
<section class="ces-pagination" v-if='isPagination'>
<el-pagination style='display: flex;justify-content: center;height: 100%;align-items: center;'
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total,sizes ,prev, pager, next,jumper"
:page-size="pagination.pageSize"
:current-page="pagination.pageNum"
:total="pagination.total"
></el-pagination>
</section>
</section>
</template>
<script>
export default {
props:{
// 表格型号:mini,medium,small
size:{type:String,default:'medium'},
isBorder:{type:Boolean,default:true},
loading:{type:Boolean,default:false},
// 表格操作
isHandle:{type:Boolean,default:false},
tableHandles:{type:Array,default:()=>[]},
// 表格数据
tableData:{ type:Array,default:()=>[]},
// 表格列配置
tableCols:{ type:Array,default:()=>[]},
// 是否显示表格复选框
isSelection:{type:Boolean,default:false},
defaultSelections:{ type:[Array,Object], default:()=>null},
// 是否显示表格索引
isIndex:{type:Boolean,default:false},
indexLabel: {type:String,default:'序号'},
// 是否显示分页
isPagination:{type:Boolean,default:true},
// 分页数据
pagination:{ type:Object,default:()=>({pageSize:10,pageNum:1,total:0})},
},
data(){
return {
}
},
watch:{
'defaultSelections'(val) {
this.$nextTick(function(){
if(Array.isArray(val)){
val.forEach(row=>{
this.$refs.cesTable.toggleRowSelection(row)
})
}else{
this.$refs.cesTable.toggleRowSelection(val)
}
})
}
},
methods:{
// 表格勾选
select(rows,row){
this.$emit('select',rows,row);
},
// 全选
selectAll(rows){
this.$emit('select',rows)
},
//
handleCurrentChange(val){
this.pagination.pageNum = val;
this.$emit('refresh');
},
handleSizeChange(val) {
this.pagination.pageSize = val;
this.$emit('refresh');
},
// tableRowClassName({rowIndex}) {
// if (rowIndex % 2 === 0) {
// return "stripe-row";
// }
// return "";
// }
renderHeader(h,obj) {
return h('span',{class:'ces-table-require'},obj.column.label)
},
},
}
</script>
<style>
.ces-table-require::before{
content:'*';
color:red;
}
.el-pagination{
float: right;
margin-right: 10px;
margin-top: 5px;
}
</style>
二、引用组件
下面是我项目的代码,有些多余的代码我就不删除了,,我会在代码里备注每个代码块的作用,也方便自己清楚。
<template>
<div class="ces-main">
<search-form
ref="form"
size='mini'
labelWidth = '50px'
:searchData = "searchData"
:searchForm = "searchForm"
:searchHandle="searchHandle"></search-form>
<ces-table
size='mini'
:isSelection='true'
:isIndex='true'
:isPagination='true'
:isHandle='true'
:tableData='tableData'
:tableCols='tableCols'
:pagination='pagination'
@refresh="handleCurrentChange"
>
</ces-table>
</div>
</template>
<script>
import {
getTableAndForm, //获取资产目录详情下的数据展示的动态表格和表单
} from '@/api/assetsManage/table/index.js';
import {
getQuery //查询接口
} from '@/api/assetsManage/assets/index.js';
//引入组件
import SearchForm from '@/components/form.vue'
import cesTable from '@/components/table.vue'
export default {
data(){
//表单查询一般分为input,下拉框,和日期,下面是下拉框时的设置下拉信息的情况,我的项目没有用到,但是留着方便看
//let sexs=[{label:'男',value:'M'},{label:'女',value:'F'}]
// let sexProps={label:'label',value:'value'}
return {
searchData:{ //查询表单的对应的值
// name:'',
// sex:null,
},
searchForm:[ //这里是渲染查询表单的表头和类型的数据
// {type:'Input',label:'姓名',prop:'name', width:'180px',placeholder:'请输入姓名...'},
// {type:'Select',label:'性别',prop:'sex',width:'180px',options:sexs,props:sexProps,change:row=>'',placeholder:'请选择性别...'},
],
searchHandle:[ //查询和重置按钮
{label:'查询',type:'primary',handle:this.handleQuery},
{label:'重置',type:'primary',handle:this.handleReset}
],
apiId:'null',
fieldList:[],
// 表格
tableData:[],//表格数据
tableCols:[ //表格列数据
// {label:'姓名',prop:'name'},
// {label:'年龄',prop:'age'},
],
// tableHandles:[ //这是表格和表单之间的一个按钮,我的项目不需要
// {label:'新增',type:'primary',handle:row=>''}
// ],
pagination:{ //分页数据
pageSize:10,
pageNum:1,
total:0
},
}
},
components:{ //引入组件后注册组件
cesTable,
SearchForm
},
mounted(){
this.getTableAndForm()
},
methods:{
//此方法是点击分页时触发的查询,
handleCurrentChange(){
this.getQuery()
},
//获取表格和表单数据
async getTableAndForm(){
//...
},
//查询
getQuery(){
//...
},
handleQuery(){ //查询
this.getQuery()
},
handleReset(){ /重置
for(var i in this.searchData){
this.$set( this.searchData, i, '')
}
this.getQuery()
}
}
}
</script>
<style lang="scss" scoped>
</style>
好了,定义组件是为了方便使用,希望在记录自己学习的时候,也可以帮到你!