文章目录
- 概要
- h-table的封装过程
- 查询组件封装 h-highForm
- 结果页
- 右侧工具栏封装RightToolbar
- 结果页
- 列表组件h-table
- 结果页
- vue页面使用
- js文件
- 有需要的请私信博主,还请麻烦给个关注,博主不定期更新组件封装,或许能够有所帮助!!请关注公众号
概要
如何使用vue封装列表高级查看,表格多种配置使用
h-table的封装过程
(1)高级查询
(2)table表格
(3)tool工具设置栏
三大组件共同合成封装表格组件
查询组件封装 h-highForm
<template>
<div class="high-form">
<!-- 左侧筛选查询 -->
<el-input
placeholder="请输入内容"
v-model="inputValue"
@keydown.enter.native="search"
class="input-with-select"
>
<el-select
class="el-select"
v-model="selectValue"
slot="prepend"
:placeholder="
selectList && selectList.length > 0 ? selectList[0].label : '暂无数据'
"
>
<el-option
v-for="v in selectList"
:key="v.value"
:label="v.label"
:value="v.value"
>
</el-option>
</el-select>
<!-- 清除按钮 -->
<i
slot="suffix"
v-if="inputValue"
@click="leftClear"
class="el-input__icon el-icon-circle-close"
></i>
</el-input>
<!-- 外面的查询按钮 -->
<el-button type="primary" @click="search" class="query-button-custom">
查询
</el-button>
<!-- 右侧高级查询表单 -->
<zy-dropdown
trigger="click"
placement="bottom"
ref="dropDown"
width="500"
v-show="showSearch"
v-if="highForm.length > 0"
:hide-on-click="false"
@visible-change="visibleChange"
>
<el-button>
{{
isShowDropdown
? "收起查询"
: count
? `高级查询(${count})`
: "高级查询"
}}<i
:class="
isShowDropdown
? 'el-icon-arrow-up el-icon--right'
: 'el-icon-arrow-down el-icon--right'
"
></i>
</el-button>
<el-dropdown-menu slot="dropdown" :class="isTabItem ? 'nav-info' : ''">
<el-button type="text" class="query-title">高级查询</el-button>
<el-form
:model="model"
ref="ruleForm"
class="form-content"
label-width="120px"
>
<el-row
v-for="(items, index) in highForm"
:key="`highForm` + index"
class="el-row-box"
>
<el-col
:span="items.length <= 1 ? 24 : 12"
v-for="i in items"
:key="i.prop"
>
<el-form-item
v-if="i.definite != false"
:label="`${i.label}:`"
:prop="i.prop"
>
<el-select
v-if="i.type === 'select'"
style="width: 240px"
v-model="model[i.prop]"
:placeholder="
i.placeholder ? i.placeholder : `请选择${i.label}`
"
:remote="i.remote ? i.remote : false"
:remote-method="i.remoteMethod"
:multiple="i.multiple ? i.multiple : false"
:collapse-tags="i.collapseTags ? i.collapseTags : true"
@blur="selectBlur($event, i)"
@focus="selectFocus($event, i)"
@change="selectChange($event, i)"
popper-class="popper-class"
:popper-append-to-body="true"
filterable
clearable
>
<el-option
v-for="(j, k) in i.optList"
:key="k"
:label="
j[
i.options && i.options.label ? i.options.label : 'label'
]
"
:value="
j[
i.options && i.options.value ? i.options.value : 'value'
]
"
>
<div class="el-select__text" v-overflow-tooltip>
{{
j[
i.options && i.options.label
? i.options.label
: "label"
]
}}
</div>
</el-option>
</el-select>
<el-cascader
v-else-if="i.type === 'cascader'"
style="width: 240px"
v-model="model[i.prop]"
:props="i.options ? i.options : null"
:options="i.optList"
:collapse-tags="i.collapseTags ? i.collapseTags : true"
:filterable="i.filterable ? i.filterable : true"
:placeholder="
i.placeholder ? i.placeholder : `请选择${i.label}`
"
@change="cascaderChange"
@expand-change="expandChange"
clearable
:append-to-body="true"
>
</el-cascader>
<el-date-picker
v-else-if="
i.type == 'year' ||
i.type == 'month' ||
i.type == 'date' ||
i.type == 'dates' ||
i.type == 'months' ||
i.type == 'years' ||
i.type == 'week' ||
i.type == 'datetime'
"
style="width: 240px"
v-model="model[i.prop]"
:type="i.type"
:placeholder="
i.placeholder ? i.placeholder : `请选择${i.label}`
"
:pickerOptions="
i.pickerOptions ? i.pickerOptions : pickerOptions
"
:value-format="i.format"
:format="i.type == 'week' ? 'yyyy 第 WW 周' : ''"
@change="singleChange"
:append-to-body="true"
popper-class="date-picker-pop"
>
</el-date-picker>
<el-date-picker
v-else-if="
i.type == 'daterange' ||
i.type == 'monthrange' ||
i.type == 'datetimerange'
"
style="width: 240px"
v-model="model[i.prop]"
:type="i.type"
range-separator="至"
:start-placeholder="
i.startPlaceholder ? i.startPlaceholder : '开始时间'
"
:end-placeholder="
i.endPlaceholder ? i.endPlaceholder : '结束时间'
"
:pickerOptions="
i.pickerOptions ? i.pickerOptions : pickerOptions
"
:value-format="i.format"
:append-to-body="true"
popper-class="date-picker-pop"
>
</el-date-picker>
<el-time-picker
v-else-if="i.type === 'timePicker'"
:placeholder="
i.placeholder ? i.placeholder : `请选择${i.label}`
"
v-model="model[i.prop]"
style="width: 100%"
popper-class="date-picker-pop"
></el-time-picker>
<el-switch
v-else-if="i.type == 'switch'"
v-model="model[i.prop]"
></el-switch>
<el-radio-group
v-else-if="i.type == 'radio'"
v-model="model[i.prop]"
>
<el-radio
v-for="(j, k) in i.optList"
:label="j"
:key="k"
></el-radio>
</el-radio-group>
<el-checkbox-group
v-else-if="i.type == 'checkbox'"
v-model="model[i.prop]"
>
<el-checkbox
v-for="ch in i.checkboxs"
:label="ch.value"
:key="ch.value"
>{{ ch.label }}</el-checkbox
>
</el-checkbox-group>
<el-input
v-else
style="width: 240px"
:type="i.type"
clearable
v-model="model[i.prop]"
:maxlength="i.maxlength"
:placeholder="
i.placeholder ? i.placeholder : `请输入${i.label}`
"
>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<slot name="operate">
<div class="footer">
<el-button type="primary" size="mini" @click="search">
查询
</el-button>
<el-button size="mini" @click="reset">重置</el-button>
</div>
</slot>
</el-dropdown-menu>
</zy-dropdown>
</div>
</template>
<script>
import ZyDropdown from "./dropdown.vue";
export default {
name: "zy-high-form",
components: { ZyDropdown },
props: {
isTabItem: {
type: Boolean,
default: false,
},
// 搜索配置
formConfig: {
type: Array,
default: () => [],
},
// 默认查询数据,如果没有默认数据,可不传
params: {
type: Object,
default: () => {},
},
// 是否展示高级搜索
showSearch: {
type: Boolean,
default: () => true,
},
autoParams: Function,
},
data() {
return {
//高级查询展示/隐藏
isShowDropdown: false,
pickerOptions: {
disabledDate: (time) => {
const day = 365 * 24 * 3600 * 1000; // 31536000000
// 返回小于当前日期并近一年内的日期
return (
time.getTime() > Date.now() ||
time.getTime() < Date.now() - 8.64e7 - day
);
},
},
// 查询数据源
model: {},
// 下拉框的值
selectValue: "firstKeyWord",
// 输入框的值
inputValue: "",
// 已选数量
count: 0,
};
},
created() {
// 在组件挂载后设置日期选择器的z-index样式
const datePickerPop = document.querySelector(
".date-picker-pop .el-picker-panel"
);
if (datePickerPop) {
datePickerPop.style.zIndex = 2000;
}
this.resetModel();
},
computed: {
//左侧下拉框
selectList() {
const list = [{ label: "全部", value: "firstKeyWord" }];
for (let i = 0; i < this.formConfig.length; i++) {
const item = this.formConfig[i];
if (item.nimble == true) {
const key = item.prop;
const capitalizedFirst = key[0].toUpperCase();
const rest = key.slice(1);
const text = capitalizedFirst + rest;
list.push({
label: item.label,
value: `first${text}`,
});
}
if (list.length > 6) break;
}
return list;
},
//处理搜索样式
searchParams() {
const model = JSON.parse(JSON.stringify(this.model));
//对于非规则数据结构,支持自定义整理数据结构
if (this.autoParams) {
return this.autoParams(model);
}
for (let i = 0; i < this.formConfig.length; i++) {
const config = this.formConfig[i];
// 对时间范围数据结构进行处理
if (
config.type &&
(config.type == "daterange" ||
config.type == "monthrange" ||
config.type == "datetimerange")
) {
if (model[config.prop] && model[config.prop].length > 1) {
model[config.prop + "BeginDate"] = model[config.prop][0];
model[config.prop + "EndDate"] = model[config.prop][1];
}
delete model[config.prop];
}
}
return model;
},
//高级查询数量
highForm() {
const list = [];
let items = [];
for (let i = 0; i < this.formConfig.length; i++) {
const item = this.formConfig[i];
if (items.length > 1) {
list.push(items);
items = [];
}
if (item.definite != false) {
items.push(item);
}
}
if (items.length != 0) {
list.push(items);
}
return list;
},
},
watch: {
selectValue: {
deep: true,
immediate: true,
handler(newVal, oldVal) {
if (oldVal) {
this.model[oldVal] = "";
}
if (newVal) {
this.model[newVal] = this.inputValue;
}
},
},
inputValue(newVal) {
this.model[this.selectValue] = newVal;
},
params: {
deep: true,
immediate: true,
handler() {
this.mergeModel();
},
},
formConfig: {
deep: true,
immediate: true,
handler(val) {
//如果配置发生了变化,重置数据
if (val && Object.keys(val).length != val.length) {
this.initData();
}
},
},
},
methods: {
// 显示菜单项
showDropDown() {
this.$refs.dropDown.show();
},
// 下拉框选中
selectChange(event, i) {
if (i.change) {
i.change(event, i);
}
this.$emit("change", event, i);
},
selectBlur(e, config) {
if (config.blur) {
config.blur(e, config);
}
this.$emit("blur", e, config);
//下拉框需要刷新才能展示tooltip
this.$forceUpdate();
},
selectFocus(e, config) {
if (config.focus) {
config.focus(e, config);
}
this.$emit("focus", e, config);
//下拉框需要刷新才能展示tooltip
this.$forceUpdate();
},
// 选中日期
expandChange(val) {
// if(val) {
this.showDropDown();
// }
},
// 级联选择器选中
cascaderChange(val) {
if (val) {
this.showDropDown();
}
},
// 日期单选
singleChange(val) {
if (val) {
this.showDropDown();
}
},
//点击菜单项下拉框出现/隐藏
visibleChange(val) {
this.showNum();
this.isShowDropdown = val;
},
// 左侧清除按钮
leftClear() {
this.inputValue = "";
this.$nextTick(() => {
this.search();
});
},
// 高级查询显示已选项数量
showNum() {
let num = 0;
for (let i = 0; i < this.formConfig.length; i++) {
const prop = this.formConfig[i].prop;
const value = this.model[prop];
var numReg = /^[0-9]*$/;
var numRe = new RegExp(numReg);
const isNumber = numRe.test(value);
if (!isNumber && (!value || value == "")) continue; // 如果对应值非数字并为空,则跳过
if (
(value instanceof Array && value.length > 0) || // 数组切有值
(value && typeof value == "string" && value.length > 0) || // 字符串切有值
(!isNaN(parseFloat(value)) && isFinite(value)) // 是否位数字或者布尔类型
) {
num++;
}
}
this.count = num;
},
/**
* 主要更新外部默认数据,当初始化/重置时外部默认数据发生表更时对数据进行合并
*/
mergeModel() {
this.model = {
...this.model,
...this.params,
};
this.showNum();
},
/**
* 这里主要处理组件内搜索初始数据,初始化/重置时调用
*/
resetModel() {
const model = {
firstKeyWord: "",
};
for (let i = 0; i < this.formConfig.length; i++) {
const config = this.formConfig[i];
model[config.prop] = config.multiple ? [] : "";
if (config.nimble) {
const key = config.prop;
const capitalizedFirst = key[0].toUpperCase();
const rest = key.slice(1);
const text = "first" + capitalizedFirst + rest;
model[text] = "";
}
// 当列表数据为空,而且传了api则获取API数据
if ((!config.optList || config.optList.length == 0) && config.api) {
config
.api(config.params ? config.params : {})
.then((res) => {
config.optList = res.data;
})
.catch((err) => {
console.log(err);
});
}
}
//设置模糊查询数据
model[this.selectValue] = this.inputValue;
this.model = {
...model,
...this.params,
};
this.showNum();
},
initData() {
for (let i = 0; i < this.formConfig.length; i++) {
const config = this.formConfig[i];
// 当列表数据为空,而且传了api则获取API数据
if ((!config.optList || config.optList.length == 0) && config.api) {
config
.api(config.params ? config.params : {})
.then((res) => {
config.optList = res.data;
})
.catch((err) => {
console.log(err);
});
}
}
},
reset() {
this.resetModel();
this.$emit("reset");
//为了避免数据没及时更新,查询做延迟
setTimeout(() => {
this.search();
}, 200);
},
search() {
this.$emit("search", this.searchParams);
//显示搜索数量和关闭弹窗
this.visibleChange(false);
this.$refs.dropDown.hide();
},
},
};
</script>
<style lang="scss" scoped>
.high-form {
display: flex;
margin-bottom: 20px;
}
.right-btn {
float: right;
}
.high-form .query-button-custom {
margin-right: 15px;
}
.query-title {
height: 40px;
background: #ffffff;
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 600;
// color: #1768b4;
line-height: 24px;
margin: 0px 10px 10px 10px;
cursor: default;
}
/* 设置弹出框的宽高 */
.el-dropdown-menu {
width: auto;
padding: 10px 0px 20px 20px;
position: absolute;
}
// 左侧输入框
.input-with-select {
width: 357px;
height: 36px;
border-radius: 4px;
margin-right: 15px;
.el-select {
width: 120px;
height: 34px;
}
::v-deep .el-input-group__prepend {
height: 34px;
background-color: #fff;
}
}
::v-deep .date-picker-pop {
z-index: 2000 !important;
}
::v-deep .el-select__tags {
flex-wrap: nowrap;
overflow: hidden;
margin-left: 1px;
}
.el-select__text {
flex-wrap: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 200px;
}
::v-deep .el-tag.el-tag--info {
max-width: 150px;
}
::v-deep .el-select-dropdown {
width: 240px;
}
.form-content {
max-height: 500px;
overflow-y: auto;
}
.el-row {
max-width: 760px;
height: 58.75px; //下拉框弹出会出现界面跳动的情况
}
.el-row-box {
display: flex;
flex-wrap: nowrap;
}
.footer {
text-align: end;
padding: 10px 20px 0 0;
width: 100%;
}
::v-deep .el-form-item--medium .el-form-item__label {
line-height: 18px;
display: flex;
justify-content: flex-end;
align-items: center;
height: 36px;
}
::v-deep .el-form--inline .el-form-item {
line-height: 18px;
}
::v-deep .el-form-item {
margin-right: 20px;
}
</style>
结果页
右侧工具栏封装RightToolbar
<template>
<div class="top-right-btn" :style="style">
<el-row>
<el-tooltip
class="item"
effect="dark"
:content="__showSearch ? '隐藏搜索' : '显示搜索'"
placement="top"
v-if="search"
>
<el-button
size="mini"
circle
icon="el-icon-search"
@click="toggleSearch()"
/>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
content="刷新"
placement="top"
v-if="renew"
>
<el-button
size="mini"
circle
icon="el-icon-refresh"
@click="refresh()"
/>
</el-tooltip>
<el-tooltip
class="item"
effect="dark"
content="显隐列"
placement="top"
v-if="columns && menu"
>
<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
:titles="['显示', '隐藏']"
v-model="value"
:data="columns"
@change="dataChange"
></el-transfer>
</el-dialog>
</div>
</template>
<script>
export default {
name: "RightToolbar",
data() {
return {
// 显隐数据
value: [],
// 弹出层标题
title: "显示/隐藏",
// 是否显示弹出层
open: false,
__showSearch: true,
};
},
props: {
showSearch: {
type: Boolean,
default: true,
},
columns: {
type: Array,
},
search: {
type: Boolean,
default: true,
},
gutter: {
type: Number,
default: 10,
},
//是否展示刷新按钮
renew: {
type: Boolean,
default: true,
},
menu: {
type: Boolean,
default: true,
},
},
watch: {
search: {
immediate: true,
handler(val) {
if (val == false) {
this.$nextTick(() => {
this.__showSearch = true;
this.toggleSearch();
});
}
},
},
showSearch: {
immediate: true,
handler(val) {
if (val != this.__showSearch) {
this.__showSearch = val;
}
},
},
},
computed: {
style() {
const ret = {};
if (this.gutter) {
ret.marginRight = `${this.gutter / 2}px`;
}
return ret;
},
},
created() {
// 显隐列初始默认隐藏列
for (let item in this.columns) {
if (this.columns[item].visible === false) {
this.value.push(parseInt(item));
}
}
},
methods: {
// 搜索
toggleSearch() {
this.__showSearch = !this.__showSearch;
this.$emit("update:showSearch", this.__showSearch);
},
// 刷新
refresh() {
this.$emit("queryTable");
},
// 右侧列表元素变化
dataChange(data) {
for (let 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="scss" scoped>
::v-deep .el-transfer__button {
border-radius: 50%;
padding: 12px;
display: block;
margin-left: 0px;
}
::v-deep .el-transfer__button:first-child {
margin-bottom: 10px;
}
</style>
结果页
列表组件h-table
<template>
<div id="BasicTable">
<zy-high-form
v-if="showSearch"
:form-config="bindTableOptions.formConfig"
:auto-params="bindTableOptions.autoParams"
:show-search="showSearch"
:params="params"
@search="__refreshList"
@reset="__reset"
@blur="highFormBlur"
@focus="highFormFocus"
@change="highFormChange"
ref="searchForm"
>
</zy-high-form>
<el-row v-if="$slots.header">
<slot name="header" />
</el-row>
<el-row>
<slot name="operator" />
<right-toolbar
v-if="
bindTableOptions.showRightToolbar != null
? bindTableOptions.showRightToolbar
: true
"
:showSearch.sync="showSearch"
:search="bindTableOptions.search"
:renew="bindTableOptions.refresh"
:menu="bindTableOptions.menu"
@queryTable="__getList"
:columns="columns"
></right-toolbar>
</el-row>
<el-table
ref="table"
v-bind="bindTableOptions"
:key="tableKey"
:row-key="rowKey"
:data="list"
v-loading="loading"
style="width: 100%"
v-on="$listeners"
:header-cell-style="{ fontWeight: 'bold', color: '#333' }"
:default-sort="bindTableOptions.sortable ? bindTableOptions.sortable : {}"
@sort-change="__onSortChange"
@row-click="__rowClick"
@selection-change="__handleSelectionChange"
>
<template
v-for="(item, index) in bindTableOptions &&
bindTableOptions.table.columns"
>
<!-- 需要自定义表格列样式 -->
<el-table-column
v-if="item.custom && item.visible && !item.columns"
v-bind="item"
:min-width="item.minWidth || 150"
:key="item.prop"
>
<template slot-scope="scope">
<slot :name="item.prop" :row="scope.row" :column="item"> </slot>
</template>
</el-table-column>
<el-table-column
v-bind="item"
:min-width="item.minWidth || 150"
v-if="!item.custom && item.visible && !item.columns"
:key="index"
show-overflow-tooltip
>
</el-table-column>
<el-table-column
v-if="item.visible && item.columns"
v-bind="item"
:min-width="item.minWidth || 180"
:key="index"
>
<template slot-scope="scope">
<zy-tool
:config="item"
:scope="scope"
@click="__handleClickAction"
:key="toolKey"
>
</zy-tool>
</template>
</el-table-column>
</template>
</el-table>
<div class="page_box" v-if="showPagination">
<pagination
:total="pagination.total"
:page.sync="pagination.pageNum"
:limit.sync="pagination.pageSize"
:page-sizes="pageSizes"
@pagination="__getList"
/>
</div>
</div>
</template>
<script>
import ZyTool from "./tool.vue";
export default {
name: "zy-table",
components: { ZyTool },
props: {
//搜索条件默认数据,如果没有默认数据可以不填
params: {
type: Object,
default: () => {},
},
//表格高度
height: String,
//是否展示底部分页
showPagination: {
type: Boolean,
default: true,
},
pageSizes: {
type: Array,
default: () => {
return [10, 20, 30, 50, 100];
},
},
pageSize: {
type: Number,
default: 10,
},
rowKey: {
type: String,
default: "id",
},
},
data() {
return {
columns: [],
tableKey: new Date().getMilliseconds(),
loading: false,
showSearch: true,
// 分页详情
pagination: {
pageSize: this.pageSize,
pageNum: 1,
total: 0,
},
sort: {
prop: "", //排序字段名
order: "", // 排序方式
},
// 列表数据
list: [],
//行选中数据
multipleSelection: [],
//存在列表数据变更,操作栏数据没变更的情况,因此这里设置key
toolKey: new Date().getTime(),
};
},
computed: {
bindTableOptions() {
return {
height: this.height ?? `calc(100vh - ${this.showSearch ? 298 : 240}px)`, // 根据是否隐藏搜索栏调整高度
...this.$attrs,
};
},
sortParams() {
//如果排序字段不存在,则由服务端自主排讯
if (!this.sort.order) return {};
return {
prop: this.sort.prop,
order: this.sort.order == "ascending" ? "asc" : "desc",
};
},
},
watch: {
columns: {
deep: true,
handler() {
this.__resetColumns();
},
},
showSearch: {
deep: true,
handler(val) {
this.$emit("showChange", this.showSearch);
},
},
"bindTableOptions.sortable": {
deep: true,
immediate: true,
handler(val) {
if (val) {
this.sort = JSON.parse(JSON.stringify(val));
}
},
},
"bindTableOptions.multipleSelection": {
deep: true,
immediate: true,
handler(val) {
if (val) {
const valStr = JSON.stringify(val);
const selection = JSON.stringify(this.multipleSelection);
if (valStr != selection) {
this.multipleSelection = JSON.parse(valStr);
}
}
},
},
},
created() {
this.columns = this.bindTableOptions.table.columns.map((v, i) => {
return { key: i, label: v.label, visible: v.visible ?? true };
});
// 初始化搜索
// 初始化搜索
if (this.bindTableOptions.autoSearch != false) {
this.$nextTick(() => {
this.__getList();
});
}
//如果配置不展示右上角的操作栏搜索功能,顶部的搜索同时不展示
if (this.bindTableOptions.search == false) {
this.showSearch = false;
}
},
methods: {
/**
* 重置列隐藏设置
*/
__resetColumns() {
// 遍历设置列数据
this.bindTableOptions.table.columns.forEach((v) => {
// 遍历隐藏/展示列设置数据
this.columns.forEach((v2) => {
// 对普通列同步隐藏/展示状态
if (v.label == v2.label) {
v.visible = v2.visible;
}
});
});
this.$nextTick(() => {
this.tableKey = new Date().getMilliseconds();
});
},
__onSortChange({ prop, order }) {
this.sort.prop = prop;
this.sort.order = order;
this.__getList();
},
//重置页码为1
__refreshList() {
this.pagination.pageNum = 1;
this.__getList();
},
// 刷新列表
__getList() {
if (!this.bindTableOptions.api) return;
const params = {
...this.getModel(),
...this.pagination,
...this.sortParams,
};
//删除总页数
delete params.total;
this.loading = true;
this.bindTableOptions
.api(params)
.then((res) => {
this.loading = false;
// this.list = res.rows ? res.rows : this.handleTree(res.data);
const rows = res.rows ? res.rows : res.data;
this.list = rows;
this.$emit("update-list", rows);
this.$emit("update", res);
this.toolKey = new Date().getTime();
this.pagination.total = res.total;
const selections = JSON.parse(JSON.stringify(this.multipleSelection));
this.clearSelection();
selections.forEach((row) => {
this.toggleRowSelection(row, true);
});
})
.catch((err) => {
this.loading = false;
});
},
// 点击操作栏
__handleClickAction(type, scope, btn) {
// 对需要进行二次确认的进行二次确认。
if (btn.confirm) {
this.$confirm(btn.msg ? btn.msg : `您确定${btn.text}吗?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.$emit("handleClickAction", type, scope, btn);
})
.catch(() => {});
return;
}
this.$emit("handleClickAction", type, scope, btn);
},
/**
* 选中行回调
* @param {选中行源数据} row
* @param {选择列配置} column
* @param {选中事件} event
*/
__rowClick(row, column, event) {
//回调点击行事件
this.$emit("row-click", row, column, event);
// 点击表格行切换selection状态
if (this.bindTableOptions.rowClickSelection) {
var result = this.multipleSelection.some(
(item) =>
item[this.bindTableOptions.rowKey ?? "id"] ===
row[this.bindTableOptions.rowKey ?? "id"]
);
this.toggleRowSelection(row, !result);
}
},
/**
*
* @param {发生变化的表格} selection
*/
__handleSelectionChange(selection) {
this.multipleSelection = JSON.parse(JSON.stringify(selection));
this.$emit("selection-change", this.multipleSelection);
},
/**
* 数据重置,当没有默认数据时可以不处理,如默认时间,需要在reset回调中重置默认时间
*/
__reset() {
this.$emit("reset");
},
/**
* 刷新数据
* @param {是否重置页码} reset
*/
refresh(reset) {
if (reset) {
this.pagination.pageNum = 1;
}
this.__getList();
},
// 获取表格实例
getTableRef() {
if (this.$refs.table) {
return this.$refs.table;
}
},
/**
* 获取搜索条件
*/
getModel() {
if (this.$refs.searchForm) {
return this.$refs.searchForm.searchParams;
}
return { ...(this.params ?? {}) };
},
/**
* 获取表格查询结果
*/
getData() {
return this.list;
},
/**
* 对表格行进行选择状态设置
* @param {操作行数据} row
* @param {选中状态} selection
*/
toggleRowSelection(row, selection = true) {
this.$refs.table.toggleRowSelection(row, selection);
},
clearSelection() {
this.$refs.table.clearSelection();
},
highFormBlur(event, config) {
this.$emit("blur", event, config);
},
highFormFocus(event, config) {
this.$emit("focus", event, config);
},
highFormChange(event, config) {
this.$emit("change", event, config);
},
},
};
</script>
<style lang="scss" scoped>
.page_box {
margin-top: 20px;
}
.dropdown-menu-btn {
margin-top: 2px !important;
}
::v-deep .el-table__empty-block {
width: 100%;
min-width: 100%;
max-width: 100%;
// padding-right: 100%;
}
::v-deep .el-table__empty-text {
line-height: normal;
}
.el-button + .el-button {
margin-left: 10px;
}
.el-table {
margin-top: 10px;
}
</style>
结果页
vue页面使用
<template>
<div class="app-container">
<zy-table
ref="ZYTable"
v-bind="tableOptions"
@handleClickAction="handleClickAction"
>
<template #operator>
<el-button
type="primary"
plain
size="small"
icon="el-icon-plus"
@click="handleAdd"
v-hasPermi="['marketing:agent:add']"
>新增经纪人</el-button
>
</template>
</zy-table>
<!-- 编辑经纪人 -->
<edit-dialog
ref="dialog"
@refresh="refresh"
></edit-dialog>
</div>
</template>
<script>
import columns, { formConfig } from "./table-config";
import { getAgentList,deleteAgent} from "@/api/marketing/agent";
import EditDialog from "./edit.vue";
export default {
name: "Agent",
components: {
EditDialog
},
data() {
return {
tableOptions: {
table: columns,
api: getAgentList,
formConfig: formConfig,
},
};
},
activated() {
this.refresh()
},
methods: {
handleClickAction(type, scope, btn) {
switch (type) {
case "edit":
this.handleEdit(scope.row);
break;
case "delete":
this.handleDelete(scope.row);
break;
}
},
// 新增
handleAdd() {
this.$refs.dialog.open(false);
},
// 编辑
handleEdit(row) {
this.$refs.dialog.open(true,row);
},
// 删除
handleDelete(row) {
deleteAgent({ activityReBrokerId: row.id }).then(res => {
this.refresh();
this.$message.success("删除成功!");
})
},
refresh() {
this.$refs.ZYTable.refresh();
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .fileUrl {
.cell {
padding: 2px 0;
display: flex;
align-items: center;
justify-content: center;
.el-image__error {
padding: 0 10px;
font-size: 12px;
}
}
}
</style>
js文件
import { getConfigList } from "@/api/marketing/configuration";
import { emptyTextFormatter } from "@/utils/tableFormatter";
// 操作列
export const actionColumns = [
{
text: "编辑",
event: "edit",
type: "text",
has: "marketing:agent:edit",
},
{
text: "删除",
event: "delete",
type: "text",
has: "marketing:agent:delete",
confirm: true,
msg: "您确定删除该经纪人信息吗?",
},
];
// 表格列
const tableColumns = [
{
type: "index",
label: "序号",
width: "60",
align: "center",
},
{
prop: "name",
label: "姓名",
minWidth: "120",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "phone",
label: "联系电话",
minWidth: "120",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "marketActivityName",
label: "所属项目",
minWidth: "200",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "channelsTypeStr",
label: "渠道身份",
minWidth: "120",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "registerSourceStr",
label: "注册来源",
minWidth: "120",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "registerDate",
label: "注册时间",
minWidth: "180",
align: "center",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "consultant",
label: "置业顾问",
minWidth: "120",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "createUserName",
label: "创建人",
minWidth: "120",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "createDate",
label: "创建时间",
align: "center",
width: "180px",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "updateUserName",
label: "更新人",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "updateDate",
label: "更新时间",
align: "center",
width: "180px",
"show-overflow-tooltip": true,
formatter: emptyTextFormatter,
},
{
prop: "",
label: "操作",
columns: actionColumns,
fixed: "right",
align: "center",
},
];
export const formConfig = [
{
type: "input",
prop: "name",
label: "姓名",
placeholder: "请输入姓名",
nimble: true,
},
{
type: "input",
prop: "consultant",
label: "置业顾问",
placeholder: "请输入置业顾问",
nimble: true,
},
{
type: "input",
prop: "phone",
label: "联系电话",
placeholder: "请输入联系电话",
nimble: true,
},
{
type: "daterange",
prop: "register",
label: "注册时间",
format: "yyyy-MM-dd",
pickerOptions: {},
},
{
type: "select",
prop: "marketActivityIds",
label: "所属项目",
placeholder: "请选择所属项目",
multiple: true,
api: getConfigList,
options: {
label: "marketActivityName",
value: "id",
},
},
{
type: "select",
prop: "channelsTypes",
label: "渠道身份",
placeholder: "请选择渠道身份",
multiple: true,
// api: getRoomStatus,
// options: {
// label: "label",
// value: "id",
// },
optList: [
{ value: "0", label: "自由经纪人" },
{ value: "1", label: "渠道商" },
{ value: "2", label: "内部员工" },
{ value: "3", label: "招商人员" },
{ value: "4", label: "运营人员" },
],
},
{
type: "select",
prop: "registerSource",
label: "注册来源",
placeholder: "请选择注册来源",
// api: getUseType,
// options: {
// label: "label",
// value: "id",
// },
optList: [
{ value: "0", label: "小程序" },
{ value: "1", label: "注册后台" },
],
},
{
type: "input",
prop: "createUserName",
label: "创建人",
placeholder: "请输入创建人",
},
{
type: "daterange",
prop: "create",
label: "创建时间",
format: "yyyy-MM-dd",
pickerOptions: {},
},
{
type: "input",
prop: "updateUserName",
label: "更新人",
placeholder: "请输入更新人",
},
{
type: "daterange",
prop: "update",
label: "更新时间",
format: "yyyy-MM-dd",
pickerOptions: {},
},
];
export default {
columns: tableColumns,
};