在后台开发中,有很多页面都是一个form搜索查询和一个table展示,所以我们可以把这两个封装成组件进行复用。
form组件功能有文本框、选择框、switch开关、日期下拉等常用搜索框,留一个插槽可以自定义一些按钮。
<template>
<!--是否行内表单-->
<el-form :inline="inline" :model="form" :rules="rules" ref="form" label-width="100px">
<!--标签显示名称-->
<el-form-item v-for="item in formLabel" :key="item.model" :label="item.label" :prop="item.model">
<!--根据type来显示是什么标签-->
<el-input v-model="form[item.model]" :placeholder="'请输入' + item.label" v-if="item.type==='input'"></el-input>
<el-select v-model="form[item.model]" placeholder="请选择" v-if="item.type === 'select'">
<!--如果是select或者checkbox 、Radio就还需要选项信息-->
<el-option v-for="item in item.opts" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
<el-switch v-model="form[item.model]" v-if="item.type === 'switch'"></el-switch>
<el-date-picker v-model="form[item.model]" type="date" placeholder="选择日期" v-if="item.type === 'date'" value-format="yyyy-MM-dd"> </el-date-picker>
</el-form-item>
<!--留一个插槽-->
<el-form-item>
<slot></slot>
<el-button type="default" @click="reset">重置</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
//inline 属性可以让表单域变为行内的表单域
//form 表单数据 formLabel 是标签数据
props: {
inline: Boolean,
form: Object,
formLabel: Array,
rules: Object
},
methods: {
reset() {
this.$refs['form'].resetFields()
},
}
}
</script>
table组件功能有序号、列表内容展示、操作按钮的展示和分页处理。
<template>
<div class="common-table">
<!--stripe 是否为斑马纹 v-loading在请求数据未返回的时间有个加载的图案,提高用户体验-->
<el-table :data="tableData" height="90%" stripe v-loading="config.loading">
<!--第一行为序号 默认写死-->
<el-table-column label="序号" width="85">
<!--slot-scope="scope" 这里取到当前单元格,scope.$index就是索引 默认从0开始这里从1开始-->
<template slot-scope="scope">
{{ (config.page - 1) * 20 + scope.$index + 1 }}
</template>
</el-table-column>
<!--show-overflow-tooltip 当内容过长被隐藏时显示 tooltip-->
<el-table-column show-overflow-tooltip v-for="item in tableLabel" :key="item.prop" :label="item.label" :width="item.width ? item.width : 125">
<!--其实可以在上面:prop="item.prop"就可以显示表单数据 这里设置插槽的方式话更加灵活 我们可以写样式-->
<template slot-scope="scope">
{{ scope.row[item.prop] }}
</template>
</el-table-column>
<!--操作-->
<el-table-column label="操作" min-width="210">
<template slot-scope="scope">
<el-button size="min" @click="handleDetail(scope.row)" v-if="config.isDetail">详情</el-button>
<el-button size="min" @click="handleEdit(scope.row)" v-if="config.isEdit">编辑</el-button>
<el-button size="min" type="danger" @click="handleDelete(scope.row)" v-if="config.isDel">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--分页-->
<el-pagination class="pager" layout="prev, pager, next" :total="config.total" :current-page.sync="config.page" @current-change="changePage" :page-size="20"></el-pagination>
</div>
</template>
<script>
export default {
//config 控制按钮和分页信息
//tableData 表格数据 tableLabel 是标签数据
props: {
tableData: Array,
tableLabel: Array,
config: Object
},
methods: {
//详情
handleDetail(row) {
this.$emit('goDetail', row)
},
//更新
handleEdit(row) {
this.$emit('edit', row)
},
//删除
handleDelete(row) {
this.$emit('del', row)
},
//分页
changePage(page) {
this.$emit('changePage', page)
}
}
}
</script>
父组件传入对应的配置
<template>
<div class="app-container">
<From ref="formParent" :inline="isInline" :form="Form" :rules="Formrules" :formLabel="FormLabel">
<template slot>
<el-button type="primary" @click="confirm">搜索</el-button>
</template>
</From>
<Table :tableData="tableData" :tableLabel="tableLabel" :config="config" @changePage="getList()" @edit="editUser" @del="delUser"></Table>
</div>
</template>
<script>
import From from './form.vue'
import Table from './table.vue'
export default {
components: {
From,
Table
},
data() {
return {
isInline: true,
Form: {
name: '',
age: '',
sex: '',
birth: '',
addr: ''
},
Formrules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' }
],
},
FormLabel: [
{
model: 'name',
label: '姓名',
type: 'input'
},
{
model: 'age',
label: '年龄',
type: 'input'
},
{
model: 'sex',
label: '性别',
type: 'select',
opts: [
{
label: '男',
value: 1
},
{
label: '女',
value: 0
}
]
},
{
model: 'birth',
label: '出生日期',
type: 'date'
},
{
model: 'addr',
label: '地址',
type: 'input'
}
],
tableData: [],
tableLabel: [
{
prop: 'name',
label: '姓名'
},
{
prop: 'age',
label: '年龄'
},
{
prop: 'sex',
label: '性别'
},
{
prop: 'birth',
label: '出生日期',
width: 200
},
{
prop: 'addr',
label: '地址',
width: 320
}
],
config: {
isEdit: true,
isDel: true,
isDetail: false,
page: 1,
total: 30,
loading: false
},
}
},
created() {
this.getList()
},
methods: {
confirm(formName) {
this.$refs.formParent.$refs['form'].validate((valid) => {
if (valid) {
console.log(this.Form)
} else {
console.log('error submit!!');
return false;
}
});
},
getList() {
this.config.loading = true
this.tableData = [{
id: 1,
name:'张三',
age: 12,
sex: '男',
birth: '1999-01-01',
addr:'北京市'
},{
id: 2,
name:'李四',
age: 15,
sex: '女',
birth: '1991-01-01',
addr:'北京市'
}]
this.config.loading = false
},
editUser(row) {
console.log(row)
this.$message('修改成功!')
},
delUser(row) {
this.$message('删除成功!')
},
goDetail(row) {
this.$message('跳转详情!')
},
changePage(page) {
this.config.page = page
this.getList()
}
}
}
</script>
<style scoped>
.line{
text-align: center;
}
</style>