基于element-ui的后台系统表格、dialog、筛选、自定义按钮、分页的一次性封装
方便基础业务开发封装的一套组件,基于vue2.5.x和element-ui,可以通过配置自动生成表格展示,表格新增、编辑功能、分页、筛选项、自定义显示表格数据等功能。
先上演示图片
----------------------------------
筛选部分
-----------------------------------------------------------
自定义按钮部分
--------------------------------
表格主体部分
------------
整体效果
以下为代码部分,都比较基础简单,就直接贴代码了
分别有,baseTable,baseDialogForm,customDisplay,filterGroup 4个小组件组成
baseTable部分(表格主体)
<template>
<div id="myTable">
<filterGroup :filterList="filterConfig.filter_list" :search_list="filterConfig.search_list" v-on="{getFilterData:filterData}"></filterGroup>
<div class="piliang">
<router-link class="btn-link" v-for="item in topBtnConfig" :key="item.title" :to="item.jumpPage?item.jumpAddress:''">
<el-button type="primary" :icon="item.icon" v-if="item.jumpPage">{{item.title}}</el-button>
<el-button type="primary" :icon="item.icon" @click="createOrUpdate()" v-else>{{item.title}}</el-button>
</router-link>
<!-- 自定义显示 -->
<customDisplay :customDisplayList="customDisplayList" v-on="{update_custom_display:updateCustomDisplay}"></customDisplay>
<el-button class="float-right" @click="getData(true)" icon="el-icon-refresh" :loading="loading">更新数据</el-button>
</div>
<!--主体内容区,展示表格内容-->
<el-table
class="baseTable"
:data="tableData"
border
size="small"
v-loading="loading"
tooltip-effect="dark"
ref="table"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" v-if="otherConfig.needSelect"></el-table-column>
<el-table-column
v-for="(item,index) in tableConfig"
:key="index"
:prop="item.prop"
:label="item.label"
:width="item.width?item.width:''"
:min-width="item.minWidth?item.minWidth:''"
:sortable="item.sortable?true:false"
v-if="customDisplayList[index].show"
>
<template slot-scope="scope">
<Cell v-if="item.render" :row="scope.row" :column="item" :index="scope.$index" :render="item.render"></Cell>
<span v-else>{{scope.row[item.prop]}}</span>
</template>
</el-table-column>
<el-table-column label="操作" v-if="tableBtnConfig.width" :width="tableBtnConfig.width" fixed="right" class-name="btns">
<template slot-scope="scope">
<!--扩展按钮-->
<el-button
@click="handleEmit(item.emitName, scope.row)"
v-if="tableBtnConfig.expands && tableBtnConfig.expands.length>0"
v-for="(item,index) in tableBtnConfig.expands"
:key="index"
:type="item.type?item.type:'primary'"
>{{item.name}}</el-button>
<el-button type="warning" v-if="tableBtnConfig.update&&!tableBtnConfig.isUpdateInNewPage" @click="createOrUpdate(scope.row)">编辑</el-button>
<el-button type="warning" v-else-if="tableBtnConfig.update&&tableBtnConfig.isUpdateInNewPage" @click="goTo(scope.row.id,tableBtnConfig.updateAddress)">编辑</el-button>
<el-button type="danger" v-if="tableBtnConfig.delete" @click.native="deleteItem(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 表格操作按钮 -->
<div class="table-control-box">
<el-button v-if="otherConfig.needSelect" type="info" @click="toggleSelection(tableData)">全选</el-button>
<el-button v-if="otherConfig.needSelect" type="info" @click="batchDelete()">批量删除</el-button>
<pagination class="float-right" :currentPaging="currentPaging" v-on="{sizeChange:handleSizeChange,currentChange:handleCurrentChange}"></pagination>
</div>
<!--按钮触发的表单弹窗-->
<BaseDialogForm
:title="dialogTitle"
:width="formWidth"
ref="dialogForm"
:config="formConfig"
:form-data="formModel"
:err-form="formError"
:is-edit="isEdit"
@submit="dialogSubmit"
></BaseDialogForm>
</div>
</template> <script>
import Cell from "./expand";
import BaseDialogForm from "components/baseDialogForm";
import customDisplay from "./customDisplay";
// 分页
import pagination from "components/pagination";
import filterGroup from "components/filterGroup"; export default {
name: "baseTable",
components: {
Cell,
BaseDialogForm,
pagination,
filterGroup,
customDisplay
},
props: [
// 表格配置
"tableConfig",
// 表格按钮配置
"tableBtnConfig",
// 数据接口
"theApi",
// 其他表格配置
"otherConfig",
// 上方按钮配置
"topBtnConfig",
// 筛选项配置
"filterConfig",
// 表单标题,例如用户、角色
"formTitle",
"formWidth",
// 表单配置
"formConfig",
// 表格编辑区域宽度
"gridEditWidth",
// 表单的model数据
"formData"
],
data() {
return {
// 表格加载状态
loading: false,
// 表格展示数据
tableData: [],
multipleSelection: [],
// 全选数据容器
allSelect: false,
// 筛选项
filter_data: {},
// 分页
currentPaging: { currentPage: 1, pageSize: 10, totals: 0 },
// 新增修改模态框title
dialogTitle: "",
// 表单数据
formModel: {},
// 后台输出错误信息
formError: {},
// 是否是编辑
isEdit: false,
// 自定义显示数据
customDisplayList: []
};
},
created() {
this.getData();
this.customInit(this.tableConfig);
},
methods: {
// 根据表格配置生成自定义显示数组
customInit: function(arr = []) {
this.customDisplayList = arr.map(item => {
return {
show: true,
label: item.label
};
});
},
// 获取列表数据
getData: async function(update = false) {
this.loading = true;
// 默认数据
let default_data = {
page: this.currentPaging.currentPage,
per_page: this.currentPaging.pageSize
};
// 筛选数据
let data = Object.assign(default_data, this.filter_data);
const res = await this.theApi.getData(data);
this.loading = false;
if (res.code === 200) {
update && this.$message.success("数据已更新");
const respon = res || {};
this.tableData = respon.data || []; // 给表格赋值
respon.total && (this.currentPaging.totals = respon.total);
}
},
// 新增 编辑按钮
createOrUpdate(item) {
this.$refs.dialogForm.resetForm();
item
? this.getEditData(item.id, () => {
this.$refs.dialogForm.showDialog();
})
: this.$refs.dialogForm.showDialog();
item ? (this.isEdit = true) : (this.isEdit = false);
this.dialogTitle = (item ? "编辑" : "添加") + this.formTitle;
},
// 从后台获取编辑框需要的数据,表格只用作展示作用,所以不从表格内获取数据
getEditData: async function(id, callback) {
const res = await this.theApi.getEdit(id);
if (res.code === 200) {
this.formModel = Object.assign({}, res.data[0] || {});
callback && callback();
}
},
// 模态框数据提交
dialogSubmit: async function(data) {
// 根据是否有id判断是新增还是编辑
const res = await this.theApi[data.id ? "editItem" : "addItem"](
data
);
if (res.code === 200) {
this.getData();
this.$message.success(this.dialogTitle + "成功!");
} else {
// 在表单中输出错误提示
const errList = res.errors || "";
if (errList) {
for (let key in errList) {
errList[key] = errList[key][0];
}
this.formError = errList;
}
}
},
// 处理相应父组件的事件方法
handleEmit(emitName, row) {
this.$emit(emitName, row);
},
// 编辑跳转页面
goTo: function(id, url) {
this.$router.push({
path: url,
query: { id: id }
});
},
// 删除
deleteItem: function(id) {
this.$confirm("是否删除?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
//ajax
this.theApi.deleteItem({ id: id }).then(() => {
if (res.code === 200) {
this.$message.success("删除成功");
// 刷新数据
this.getData();
}
});
})
.catch(() => {
this.$message.info("取消删除");
});
},
// 批量删除
batchDelete: function() {
if (this.multipleSelection[0]) {
this.$confirm("是否删除选择的条目?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
let data = this.multipleSelection;
//ajax
})
.catch(() => {
this.$message.info("取消删除");
});
} else {
this.$message.error("请先选择要删除的条目");
}
},
// 表格选择
handleSelectionChange: function(val) {
this.multipleSelection = val;
this.allSelect = val.length === this.tableData.length;
},
// 全选按钮
toggleSelection: function(rows) {
if (rows && !this.allSelect) {
rows.forEach(row => {
this.$refs.table.toggleRowSelection(row, true);
});
} else {
this.$refs.table.clearSelection();
}
},
// 分页sizeChange
handleSizeChange: function(val) {
this.currentPaging.pageSize = val;
this.currentPaging.currentPage = 1;
// 更新数据
this.getData();
},
// 分页currentChange
handleCurrentChange: function(val) {
this.currentPaging.currentPage = val;
// 更新数据
this.getData();
},
// 更新自定义显示组件数据
updateCustomDisplay: function(arr) {
this.customDisplayList = arr;
},
// 筛选
filterData: function(obj) {
this.tableData = [];
this.filter_data = JSON.parse(JSON.stringify(obj));
this.currentPaging.currentPage = 1;
// 刷新数据
this.getData();
}
}
};
</script> <style lang="less" scoped>
@import "~assets/css/mixin.less";
.baseTable {
width: 100%;
margin: 0.55rem 0;
/* 强制不换行 */
.btns {
.cell {
white-space: nowrap;
}
}
/deep/ thead {
th {
background: lighten(#ebeef5, 3%);
color: #333;
font-size: 14px;
}
}
.icon-text {
.iconfont {
font-size: 14px;
margin-right: 5px;
}
}
}
.table-control-box {
overflow: hidden;
}
.piliang {
margin: 0.55rem 0;
position: relative;
&::after {
.clear;
}
.btn-link {
margin-right: 10px;
float: left;
}
.el-button {
margin-left: 0;
}
}
</style>
customDisplay部分(自定义显示按钮)
<template>
<div id="customDisplay" class="float-left">
<el-button type size="mini" class="float-left" icon="el-icon-setting" @click="customDisplayShow = !customDisplayShow">自定义显示</el-button>
<div class="custom-display-dialog float-left" v-if="customDisplayShow">
<ul class="custom-display-dialog-list">
<li class="item title">当前展示的信息</li>
<li class="item">
<el-checkbox v-model="checkedAll" @change="selectAll">全选</el-checkbox>
</li>
<li class="item" v-for="(item,index) in list" :key="index">
<el-checkbox v-model="item.show" @change="select">{{item.label}}</el-checkbox>
</li>
</ul>
<!-- model -->
<div class="model" @click="customDisplayShow = false"></div>
</div>
</div>
</template> <script>
export default {
// 自定义选择组件
name: "customDisplay",
data() {
return {
customDisplayShow: false,
checkedAll: true,
list: []
};
},
props: ["customDisplayList"],
created: function() {
this.customDisplayList &&
(this.list = JSON.parse(JSON.stringify(this.customDisplayList)));
},
methods: {
// 全选
selectAll: function() {
this.list.map(item => {
item.show = this.checkedAll;
});
this.$emit("update_custom_display", this.list);
},
// 单选
select: function() {
let _list = this.list;
for (let i = 0; i < _list.length; i++) {
if (!_list[i].show) {
this.checkedAll = false;
break;
} else {
this.checkedAll = true;
}
}
this.$emit("update_custom_display", this.list);
}
}
};
</script>
<style lang="less" scoped>
@import "~assets/css/mixin.less";
#customDisplay {
margin-right: 10px;
.custom-display-dialog {
margin-left: 10px;
position: relative;
z-index: 2200;
.custom-display-dialog-list {
position: absolute;
z-index: 998;
padding: 10px 20px;
background: #fff;
border: 1px solid #ccc;
border-radius: 4px;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.15);
.item {
margin: 2px 0;
.el-checkbox {
display: block;
}
}
.title {
font-size: 16px;
white-space: nowrap;
margin-bottom: 10px;
color: #888;
padding-right: 5px;
}
}
.model {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 997;
}
}
}
</style>
baseDialogForm部分(基于表格的弹出框表单)
<template>
<el-dialog :title="title" :visible.sync="dialogVisible" :width="width?width:'80%'">
<el-form :model="formModel" ref="configForm" label-width="100px">
<el-row :gutter="16">
<el-col :span="item.span?item.span:8" v-for="(item,index) in config" :key="index">
<el-form-item :prop="item.prop" :rules="item.rules" :label="item.label">
<!--输入框表单类型-->
<el-input
v-if="item.type === 'text' || item.type === 'password' || item.type === 'textarea'"
:type="item.type"
v-model="formData[item.prop]"
:placeholder="item.placeholder?item.placeholder:'请输入'"
></el-input>
<!-- 计数器 -->
<el-input-number v-if="item.type === 'el-input-number'" v-model="formData[item.prop]" :min="1" :step="1" label="描述文字"></el-input-number>
<!--checkbox表单类型-->
<el-checkbox-group v-if="item.type === 'checkbox'" v-model="formData[item.prop]" :placeholder="item.placeholder?item.placeholder:'请选择'">
<el-checkbox v-for="option in item.data" :label="option.id" :key="option.id">{{option.name}}</el-checkbox>
</el-checkbox-group>
<!--radio表单类型-->
<el-radio-group v-if="item.type === 'radio'" v-model="formData[item.prop]" :placeholder="item.placeholder?item.placeholder:'请选择'">
<el-radio v-for="option in item.data" :label="option.id" :key="option.id">{{option.name}}</el-radio>
</el-radio-group>
<!--下拉选择类型-->
<el-select v-if="item.type === 'select'" v-model="formData[item.prop]" :placeholder="item.placeholder?item.placeholder:'请选择'">
<el-option v-for="option in item.data" :key="option.id" :label="option.label" :value="option.id"></el-option>
</el-select>
<el-date-picker v-if="item.type === 'datepicker'" v-model="formData[item.prop]" type="date" :placeholder="item.placeholder?item.placeholder:'请选择日期'"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
</el-form> <span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="submitForm(formModel)">确 定</el-button>
</span>
</el-dialog>
</template> <script>
export default {
name: "base-dialog-form",
props: [
"title",
"width",
"visible",
"config",
"formData",
"errForm",
"isEdit"
],
data() {
return {
formModel: {},
dialogVisible: false,
dialogTitle: ""
};
},
mounted() {
// 将组件上的属性赋值给当前组件内变量,因为props只能单向绑定,还需要监听属性值变化进行父子组件间交互
this.formModel = this.formData;
this.dialogVisible = this.visible;
this.dialogTitle = this.title;
},
methods: {
// 提交表单数据
submitForm(obj) {
console.log(obj);
this.$refs.configForm.validate(valid => {
if (valid) {
// 让父组件接收到响应数据
this.$emit("submit", this.formModel);
// 关闭模态框
this.dialogVisible = false;
} else {
return false;
}
});
},
// 重置表单状态
resetForm() {
if (this.$refs.configForm) {
this.$refs.configForm.resetFields();
}
},
// 展示模态框
showDialog() {
this.dialogVisible = true;
}
},
watch: {
/*实现表单数据的绑定,实时接收父组件的数据变化*/
formData() {
this.formModel = this.formData;
}
}
};
</script> <style lang="less" scoped>
.el-input {
width: 100% !important;
} .el-select {
width: 100% !important;
}
</style>
filterGroup部分(表格上方筛选项集合)
<template>
<div id="filterGroup">
<div class="filter-container" :class="{'opened':open,'big':open_btn_show}">
<!-- 筛选项 -->
<el-form :inline="true" id="formBox" ref="filterForm">
<el-form-item label="关键字:" v-if="filterOptions.search">
<el-input v-popover:popover v-model="filterData.keyword" @keyup.enter.native="getFilterData()" placeholder="请输入关键字" clearable></el-input>
<el-popover ref="popover" placement="bottom" width="200" trigger="focus" popper-class="search-popover">
<div v-if="search_list[0]">
<p class="popover-title">支持的搜索条件</p>
<ul class="popover-list">
<li class="popover-item" v-for="(item, index) in search_list" :key="index">{{item}}</li>
</ul>
</div>
<span v-else>暂无可搜索项</span>
</el-popover>
</el-form-item>
<el-form-item label="分类:" v-if="filterOptions.classify">
<el-select v-model="filterData.classify">
<el-option v-for="(item,index) in classifyList" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="年份:" v-if="filterOptions.year">
<el-select v-model="filterData.year">
<el-option v-for="(item,index) in years" :key="index" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<el-form-item label="激活状态:" v-if="filterOptions.activation">
<el-select v-model="filterData.activation">
<el-option v-for="(item,index) in activationList" :key="index.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="审核状态:" v-if="filterOptions.examine">
<el-select v-model="filterData.examine">
<el-option v-for="(item,index) in examineList" :key="index.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="操作人:" v-if="filterOptions.operator">
<el-select v-model="filterData.operator">
<el-option v-for="(item,index) in operatorList" :key="index.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="事件:" v-if="filterOptions.event">
<el-select v-model="filterData.event">
<el-option v-for="(item,index) in eventList" :key="index.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="影片推荐:" v-if="filterOptions.recommend">
<el-cascader :options="recommendList" v-model="filterData.recommend" style="width:100%;"></el-cascader>
</el-form-item>
<el-form-item label="日期:" v-if="filterOptions.date_scope" class="date-filter">
<el-date-picker
v-model="filterData.date_scope"
type="daterange"
align="right"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item :class="open_btn_show?'btn':''" v-if="!sure">
<el-button type="primary" @click="getFilterData()">查 询</el-button>
<el-button
v-if="open_btn_show"
type="primary"
plain
@click="open = !open;btn_text = !open?'展开':'收起'"
:icon="!open?'el-icon-arrow-down':'el-icon-arrow-up'"
>{{btn_text}}</el-button>
</el-form-item>
<el-form-item v-else>
<el-button type="primary" @click="getFilterData()">确 定</el-button>
</el-form-item>
</el-form>
</div>
<!-- 筛选结果项 -->
<div class="filter-result-container" v-if="filter_arr[0]">
<ul class="list">
<li class="item filter-text">
<i class="iconfont icon-filter"></i>
<span>检索项:</span>
</li>
<li class="item" v-for="item in filter_arr" :key="item.key" v-if="item.title">
<el-tag :closable="canClearFilter !== false" size="small" class="tag" @close="closeTag(item)">{{`${item.title} : ${item.value}`}}</el-tag>
</li>
<li class="item filter-text clearAll" @click="closeAllTag" v-if="showClearAllBtn !== false">清空</li>
</ul>
</div>
</div>
</template> <script>
// css
import "components/filterGroup/style.css"; export default {
// 筛选项
name: "filterGroup",
data() {
return {
// 布局状态
menuType: 1,
contentWidthType: "流式",
isCollapse: false, // 导航是否折叠
open: false,
btn_text: "展开",
open_btn_show: false,
// 映射表
filterOptions: {
search: false, // 关键字搜索
classify: false, // 分类
year: false, // 年份
activation: false, // 激活状态
examine: false, // 审核状态
recommend: false, // 影片推荐
operator: false, // 操作人
event: false, // 事件
date_scope: false // 日期选择范围
},
// 点击查询之后传到父级的筛选项数据
filterData: {},
// 筛选项数组
filter_arr: [],
// 分类
classifyList: [],
// 年份
years: [],
// 激活状态
activationList: [
{
value: 1,
label: "已激活"
},
{
value: -1,
label: "未激活"
}
],
// 审核状态
examineList: [
{
value: 1,
label: "已通过"
},
{
value: 0,
label: "未审核"
},
{
value: -1,
label: "驳回"
}
],
// 影片推荐
recommendList: [],
// 操作人
operatorList: [],
// 事件
eventList: []
};
},
props: {
// 筛选项配置 外部传入
filterList: Array,
search_list: Array, // 搜索框支持的搜索项
sure: true,
showClearAllBtn: true, // 是否显示清空按钮
canClearFilter: true // 是否能清除单个筛选
},
watch: {
listenContentWidthType(newVal) {
this.contentWidthType = newVal;
this.showBtn();
},
listenMenuType(newVal) {
this.menuType = newVal;
this.showBtn();
},
listenMenuCollapse(newVal) {
this.isCollapse = newVal;
this.showBtn();
}
},
computed: {
listenContentWidthType() {
return this.$store.state.contentWidthType;
},
listenMenuType() {
return this.$store.state.menuType;
},
listenMenuCollapse() {
return this.$store.state.menuCollapse;
},
role() {
return this.$store.state.role;
}
},
created: function() {
// 匹配显示
for (let key in this.filterOptions) {
for (let k in this.filterList) {
if (this.filterList[k] == key) {
this.filterOptions[key] = true;
}
}
}
},
mounted: function() {
const that = this;
// 首页带参数筛选
let default_filter = function() {
// 首页带参数的跳转
if (that.$route.query.show_filter === "1") {
if (that.open_btn_show) {
that.open = true;
that.btn_text = "收起";
}
let homePageFilterObj = {};
that.filterData = homePageFilterObj;
that.$emit("getFilterData", that.filterData);
that.initFilter(that.filterData);
}
};
that.showBtn(default_filter);
},
methods: {
// 判断是否需要显示展开收起按钮
showBtn: function(callback) {
// 加上300的延时 因为css切换的过渡时间是.3s
setTimeout(() => {
const formContainer = document.getElementById("formBox");
this.open_btn_show =
formContainer.clientHeight > 50 ? true : false;
// 回调函数
callback && callback();
}, 310);
},
// 传递筛选数据
getFilterData() {
let obj = this.filterData;
for (let key in obj) {
if (obj[key] === "" || obj[key] === null) {
delete obj[key];
} else {
if (key === "date_scope") {
// 拆分数组
const [exam_start_time, exam_end_time] = obj[key];
Object.assign(
obj,
{ exam_start_time },
{ exam_end_time }
);
}
}
}
this.$emit("getFilterData", obj);
this.initFilter(obj);
},
// 生成筛选项列表数据
initFilter: function(filterList = {}) {
const filter_list = filterList;
let arr = [];
for (let key in filter_list) {
if (
filter_list[key] !== "" &&
filter_list[key] !== undefined &&
filter_list[key] !== null
) {
arr.push({
key: key,
title: this.filterMap(key, filter_list[key]).title,
value: this.filterMap(key, filter_list[key]).value
});
}
}
this.filter_arr = arr;
},
// 筛选项列表字典
filterMap: function(theKey = "", theValue) {
const key = theKey;
const val = theValue;
let item = {};
switch (key) {
case "keyword":
item.title = "关键字";
item.value = val;
break;
case "date_scope":
item.title = "日期";
item.value = `${val[0]} - ${val[1]}`;
break;
case "activation":
item.title = "激活状态";
item.value = this.arrayMapFilter(
this.activationList,
val
).label;
break;
default:
item = {};
}
return item;
},
// 筛选项字典内filter
arrayMapFilter: function(list = [], value = "") {
const arr = JSON.parse(JSON.stringify(list));
let val = value;
arr.filter(el => {
if (el.value == val) {
val = el;
}
});
return val;
},
// 关闭筛选
closeTag: function(item) {
let key = item.key;
// 关联字段清除
if (item.key == "agent_id") {
//
} else {
delete this.filterData[key];
}
this.getFilterData();
},
// 清空筛选
closeAllTag: function() {
this.filterData = {};
this.getFilterData();
}
}
};
</script>
页面调用
<template>
<div id="member_list">
<!-- 表格 -->
<baseTable
:theApi="table_ajax"
:table-config="configData.tableConfig"
:top-btn-config="configData.topBtnConfig"
:table-btn-config="configData.tableBtnConfig"
:other-config="configData.otherConfig"
:filter-config="configData.filterConfig"
:grid-edit-width="200"
form-title="会员"
form-width="40%"
:form-config="configData.formConfig"
:form-data="configData.formModel"
@checkRegistration="checkRegistration"
ref="basetable"
></baseTable>
</div>
</template>
<script>
// api
import * as theApi from "api/enroll/member_list";
import baseTable from "components/baseTable";
// 类型验证
import { checkActivation, checkEntry } from "utils/checkTypes";
// 表单验证
import { checkUserName } from "utils/verify";
export default {
name: "member_list",
data() {
return {
//表格配置
configData: {
// 其他配置
otherConfig: {
needSelect: true // 是否可以多选
},
// 表格数据配置
tableConfig: [
{ label: "ID", prop: "id", width: "70" },
{ label: "用户名", prop: "username" },
{ label: "昵称", prop: "nickname" },
{ label: "注册时间", prop: "datetime", sortable: true },
{
label: "会员激活状态",
prop: "member_type",
render: (h, params) => {
const { color, text, icon } = checkActivation(
params.row.member_type
);
return (
<div class="icon-text">
<i
class={`iconfont icon-${icon}`}
style={`color:${color}`}
/>
<span style={`color:${color}`}>{text}</span>
</div>
);
}
},
{
label: "D20报名状态",
prop: "d20_type",
render: (h, params) => {
const { color, text, icon } = checkEntry(
params.row.d20_type
);
return (
<div class="icon-text">
<i
class={`iconfont icon-${icon}`}
style={`color:${color}`}
/>
<span style={`color:${color}`}>{text}</span>
</div>
);
}
},
{
label: "IDF创投报名状态",
prop: "idf_type",
render: (h, params) => {
const { color, text, icon } = checkEntry(
params.row.idf_type
);
return (
<div class="icon-text">
<i
class={`iconfont icon-${icon}`}
style={`color:${color}`}
/>
<span style={`color:${color}`}>{text}</span>
</div>
);
}
}
],
// 表格内按钮配置
tableBtnConfig: {
width: 245, //宽度
update: true, // 编辑
delete: true, // 删除
expands: [
{
name: "查看报名",
emitName: "checkRegistration",
type: "primary"
}
]
},
// 表格上方按钮配置
topBtnConfig: [
{
title: "添加会员",
icon: "el-icon-circle-plus"
}
],
// 筛选组件配置
filterConfig: {
filter_list: ["search", "year", "activation"],
search_list: ["用户名", "昵称"]
},
// table的模态框表单配置,可配置表单类型,验证规则,是否必填,col-span布局可通过span参数配置
formConfig: [
{
span: 24,
label: "用户名",
prop: "username",
type: "text",
rules: {
required: true,
validator: checkUserName,
trigger: "blur"
}
},
{
span: 24,
label: "昵称",
prop: "nickname",
type: "text",
rules: {
required: true,
message: "请输入昵称",
trigger: "blur"
}
},
{
span: 24,
label: "密码",
prop: "password",
type: "password",
rules: {
required: true,
validator: (rule, value, callback) => {
const is_edit = this.$refs.basetable.$refs
.dialogForm.isEdit; // 判断当前是编辑还是新增
const reg = /^[0-9a-zA-Z_]{6,15}$/; //6-15位数字字母下划线
if (!value) {
if (!is_edit) {
callback(new Error("密码不能为空"));
} else {
callback(); //可为空
}
} else if (reg.test(value) == false) {
callback(
new Error(
"密码必须为6~15位,英文与数字或下划线组合"
)
);
} else {
callback();
}
},
trigger: "blur"
}
},
{
span: 24,
label: "确认密码",
prop: "checkpassword",
type: "password",
rules: {
required: true,
validator: (rule, value, callback) => {
const psd = this.$refs.basetable.$refs
.dialogForm.formModel.password; // 输入的密码
const is_edit = this.$refs.basetable.$refs
.dialogForm.isEdit; // 判断当前是编辑还是新增
const reg = /^[0-9a-zA-Z_]{6,15}$/; //6-15位数字字母下划线
if (!value) {
if (!is_edit) {
callback(new Error("密码不能为空"));
} else {
callback(); //可为空
}
} else if (reg.test(value) == false) {
callback(
new Error(
"密码必须为6~15位,英文与数字或下划线组合"
)
);
} else if (value !== psd) {
callback(new Error("两次输入密码不一致!"));
} else {
callback();
}
},
trigger: "blur"
}
}
],
// 表单基础数据类型,需要预先赋值
formModel: {
username: "",
nickname: "",
password: "",
checkpassword: ""
}
},
// ajax
table_ajax: theApi
};
},
components: { baseTable },
methods: {
checkRegistration: function(row = {}) {
this.$router.push({
path: "/pages/index/enroll/entry/list",
query: { id: row.id }
});
}
}
};
</script>
基于element-ui的后台系统表格、dialog、筛选、自定义按钮、分页的一次性封装的更多相关文章
- 基于element UI 的上传插件
为了不再重复的上传文件,做了一个统一选择文件和上传文件的 基于 element UI :http://element-cn.eleme.io 前端实现文件下载和拖拽上传 演示 用法 <uploa ...
- 基于vue模块化开发后台系统——准备工作
文章目录如下:项目效果预览地址项目开源代码基于vue模块化开发后台系统--准备工作基于vue模块化开发后台系统--构建项目基于vue模块化开发后台系统--权限控制 前言 本文章是以学习为主,练习一下v ...
- 基于vue模块化开发后台系统——构建项目
文章目录如下:项目效果预览地址项目开源代码基于vue模块化开发后台系统--准备工作基于vue模块化开发后台系统--构建项目基于vue模块化开发后台系统--权限控制 前言 在熟悉上一篇说到准备工具之后, ...
- element ui table 导出excel表格
https://blog.csdn.net/u010427666/article/details/79208145 vue2.0 + element UI 中 el-table 数据导出Excel1. ...
- 基于element ui的图片预览插件
写插件很简单,满足两个条件即可,一.基本的逻辑思路,二.熟悉插件语法要求.本次Vue插件也比较简单,点击“查看图片”用轮播的方式限制用户上传的图片,如图: 项目采用的是vue-element-admi ...
- vue2.0+Element UI 实现动态表单(点击按钮增删一排输入框)
对于动态增减表单项,Element UI 官方文档表单那一节已经介绍得很清楚了,我之前没有看见,绕了很多弯路,这里针对点击按钮增删一排输入框的问题做一个总结. 效果图如下 存在一排必填的姓名与手机号, ...
- 基于element ui的级联选择器组件实现的分类后台接口
今天在做资产管理系统的时候遇到一个分类的级联选择器,前端是用的element的组件,需要后台提供接口支持. 这个组件需要传入的数据结构大概是这样的,详细的可参考官方案例: [{ value: ...
- react+react-router+mobx+element打造管理后台系统---react-amdin-element
react-admin-element,一款基于react的后台管理系统. 那么我们和其他的后台管理系统有什么区别呢? demo地址:点我进入demo演示 github地址:点我进入github 1. ...
- vue基于 element ui 的按钮点击节流
vue的按钮点击节流 场景: 1.在实际使用中,当我们填写表单,点击按钮提交的时候,当接口没返回之前,迅速的点击几次,就会造成多次提交. 2.获取验证码,不频繁的获取. 3.弹幕不能频繁的发 基于这几 ...
随机推荐
- 应用.NET控制台应用程序开发批量导入程序。
一.最近一直在调整去年以及维护去年开发的项目,好久没有在进行个人的博客了.每天抽了一定的时间在研究一些开源的框架,Drapper 以及NHibernate以及当前比较流行的SqlSuper框架 并进行 ...
- 图片轮播,信手拈来(jquery)
制作图片轮播,可以说是js或者jquery学习者应该掌握的技巧.但惭愧的是本菜之前一直一知半解,这回抽了半天多总结了下分享给大家.虽然标题比较吹牛,但目的是希望大家看了之后制作图片轮播会非常迅速. 首 ...
- MongoDB中设置expire过期自动删除
关键词: expireAfterSeconds.TTL TTL Time to Live 类似Redis中的expire机制,MongoDB也可以设置过期自动删除的表. MongoDB的过期设置依赖索 ...
- .Net Core Linux centos7行—jenkins linux 构建.net core web app
1.安装jdk.jenkins 是一个java web程序.所以必然需要jdk. yum install java 或者 yum install java-1.8.0-openjdk 2.下载jenk ...
- 14-Dockerfile常用指令
下面列出了 Dockerfile 中最常用的指令,完整列表和说明可参看官方文档.FROM 指定 base 镜像. MAINTAINER设置镜像的作者,可以是任意字符串. COPY将文件从 build ...
- 使用云负载时将http的请求转发至https时报错:“ERR_TOO_MANY_REDIRECTS”!
问题描述: 新业务正式环境部署,使用云负载(有http监听也有https监听)在我向我的 Web 服务器添加重定向逻辑后,我的网站停止工作,并且我收到错误 ERR_TOO_MANY_REDIRECTS ...
- jmeter控制器(一)
简单控制器: 也就是最简单的控制器,里面没有任何内容的,如下图所示: 当我设置线程为循环10次时,运行简单控制器及下边的注册,设置如下图: 通过查看结果数得知,注册只成功了一次 ,再注册时出现邮箱已存 ...
- 笔记:《机器学习训练秘籍》——吴恩达deeplearningai微信公众号推送文章
说明 该文为笔者在微信公众号:吴恩达deeplearningai 所推送<机器学习训练秘籍>系列文章的学习笔记,公众号二维码如下,1到15课课程链接点这里 该系列文章主要是吴恩达先生在机器 ...
- Hyperledger Fabric MSP Identity Validity Rules——MSP身份验证规则
MSP Identity Validity Rules——MSP身份验证规则 正如Hyperledger Fabric Membership Service Providers (MSP)——成员服务 ...
- 深入理解JavaScript函数参数
前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数. arguments javascri ...