sgSearch源码
<template>
<div :class="$options.name" :expand="expandSearch" :showCollapseBtn="showCollapseBtn">
<!-- v-clickoutside="(d) => (expandSearch = false)" -->
<ul class="search-list">
<slot name="searchFilter"></slot>
<ul class="sg-search-btns">
<slot name="searchBtns"></slot>
</ul>
<ul class="sg-operate-btns">
<slot name="operateBtns"></slot>
</ul>
</ul>
<!-- 折叠按钮 -->
<sgCollapseBtn v-model="expandSearch" />
</div>
</template>
<script>
import clickoutside from "element-ui/src/utils/clickoutside";
import sgCollapseBtn from "@/vue/components/admin/sgCollapseBtn";
export default {
name: "sgSearch",
directives: { clickoutside },
components: {
sgCollapseBtn,
},
data() {
return {
expandSearch: false,
showCollapseBtn: false,
defaultHeight: 50, //组件默认高度
};
},
props: [
"value", //是否显示
"disabled", //是否禁用
"collapse",
"data",
"showCollapseButton", //显示折叠按钮
],
computed: {},
watch: {
collapse: {
handler(newValue, oldValue) {
this.expandSearch = !newValue;
},
deep: true, //深度监听
immediate: true, //立即执行
},
expandSearch: {
handler(newValue, oldValue) {
this.$emit(`update:collapse`, !newValue);
this.$nextTick(() => {
this.getHeight();
// this.getTop();
});
},
deep: true, //深度监听
// immediate: true, //立即执行
},
showCollapseButton: {
handler(newValue, oldValue) {
this.$nextTick(() => {
this.getShowCollapseBtn();
});
},
deep: true, //深度监听
// immediate: true, //立即执行
},
},
created() {},
mounted() {
this.$el.style.setProperty("--defaultHeight", `${this.defaultHeight}px`); //js往css传递局部参数
this.getShowCollapseBtn();
this.$nextTick(() => {
this.getHeight();
// this.getTop();
});
},
methods: {
getHeight() {
let height = this.$el ? this.$el.getBoundingClientRect().height : 0;
this.$emit(`getHeight`, height);
},
/* getTop() {
let rect = this.$el ? this.$el.getBoundingClientRect() : null;
if (rect) {
let top = this.$el ? rect.top + rect.height : 0;
this.$emit(`getTop`, top);
}
}, */
getShowCollapseBtn(d) {
if (this.showCollapseButton === "" || this.showCollapseButton) {
this.showCollapseBtn = true;
} else if (this.showCollapseButton === false) {
this.showCollapseBtn = false;
} else {
let len_search_list = this.$el.querySelectorAll(`.search-list>li`).length;
/*let len_search_btns = this.$el.querySelectorAll(`.sg-search-btns>*`).length;
let len_operate_btns = this.$el.querySelectorAll(`.sg-operate-btns>*`).length;
let len = len_search_list + len_search_btns + len_operate_btns;
this.showCollapseBtn = len > 5; */
let searchList = this.$el.querySelector(`.search-list`);
this.showCollapseBtn =
len_search_list > 3 || searchList.offsetHeight > this.defaultHeight;
}
},
},
destroyed() {},
};
</script>
<style lang="scss" scoped>
.sgSearch {
position: relative;
$defaultHeight: var(--defaultHeight); //默认高度
$collapseHeight: 75px; //折叠高度
$expandHeight: max-content; //展开高度
$colCount: 4; //每行数量
$itemGap: 10px; //每一项间距
$itemLabelGap: 5px; //每一项标签间距
width: 100%;
flex-grow: 1;
height: $defaultHeight;
box-sizing: border-box;
.sgCollapseBtn {
display: none;
}
&[showCollapseBtn] {
padding-bottom: 30px;
height: $collapseHeight;
.sgCollapseBtn {
display: block;
}
}
& > .search-list {
width: 100%;
flex-grow: 1;
display: flex;
flex-wrap: wrap;
& > * {
flex-shrink: 0;
}
& > li {
width: calc((100% - #{$itemGap} * (#{$colCount} - 1)) / #{$colCount});
flex-wrap: nowrap;
align-items: baseline;
box-sizing: border-box;
margin-right: $itemGap;
margin-bottom: $itemGap;
display: none;
&:nth-of-type(1),
&:nth-of-type(2),
&:nth-of-type(3) {
display: flex;
}
label {
flex-shrink: 0;
margin-right: $itemLabelGap;
text-align: right;
}
&:nth-of-type(#{$colCount}n),
&:last-of-type {
margin-right: 0;
}
}
.sg-search-btns {
display: flex;
flex-wrap: nowrap;
align-items: baseline;
& > * {
margin-right: $itemGap;
}
}
.sg-operate-btns {
display: flex;
justify-content: flex-end;
align-items: baseline;
flex-wrap: nowrap;
margin-left: auto;
& > * {
margin-left: $itemGap;
}
}
}
&[expand] {
height: $expandHeight;
& > .search-list {
& > li {
display: flex;
}
}
}
}
</style>
应用
<template>
<div :class="$options.name">
<sgSearch
:collapse.sync="collapseSearch"
@keyup.enter="(collapseSearch = true), (currentPage = 1), initList()"
@getHeight="(d) => (sgSearchHeight = d)"
>
<template slot="searchFilter">
<li>
<label>搜索</label>
<el-input clearable placeholder="请输入关键词" v-model.trim="keyword" />
</li>
<li style="width: 150px">
<label>状态</label>
<el-select style="width: 100%" v-model="ZT" placeholder="请选择" clearable>
<el-option
v-for="(a, i) in ZTs"
:key="i"
:value="a.value"
:label="a.label"
></el-option>
</el-select>
</li>
<li>
<label>创建时间</label>
<el-date-picker
v-model="GXSJ"
ref="GXSJ"
type="daterange"
align="right"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="$global.pickerOptions"
clearable
/>
</li>
<li>
<label>更新时间</label>
<el-date-picker
v-model="GXSJ"
ref="GXSJ"
type="daterange"
align="right"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="$global.pickerOptions"
clearable
/>
</li>
</template>
<template slot="searchBtns">
<el-button
size="medium"
type="primary"
icon="el-icon-search"
@click="(collapseSearch = true), (currentPage = 1), initList()"
>搜索</el-button
>
<el-button
size="medium"
type="primary"
@click="resetFilterData(), initList()"
plain
>重置</el-button
>
</template>
<template slot="operateBtns">
<el-button size="medium" type="primary" @click="add">添加</el-button>
<el-button
:disabled="selection.length === 0"
size="medium"
type="danger"
@click="delAny"
>批量删除</el-button
>
</template>
</sgSearch>
<div
class="sg-table"
v-loading="loading"
:full="fullscreenTable"
@click="collapseSearch = true"
>
<el-table
:data="tableData"
ref="table"
stripe
border
:header-cell-style="{ background: '#f5f7fa' }"
:height="`calc(100vh - ${fullscreenTable ? 10 : 160 + sgSearchHeight}px - ${
total > 10 ? 40 : 0
}px)`"
:show-header="true"
style="width: 100%"
@row-click="row_click"
@selection-change="selection_change"
:row-class-name="row_class_name"
>
<template slot="empty">
<el-empty v-show="!loading" :image="require('@/assets/404.png')">
<span slot="description">暂无数据</span>
<el-button type="primary" icon="el-icon-s-promotion" plain @click="add"
>去哪里添加数据</el-button
>
</el-empty>
</template>
<el-table-column type="selection" width="50" />
<el-table-column type="index" label="序号" width="60" />
<!-- <el-table-column prop="字段" label="列名" minWidth="200" /> -->
<el-table-column :resizable="false" prop="ID" label="身份证号" minWidth="200">
<template v-slot:header="scope">
<span>
身份证号
<fullscreenTable v-model="fullscreenTable" />
</span>
</template>
<template slot-scope="scope">
<span>【索引{{ scope.$index }}】{{ scope.row.ID }}</span>
</template>
</el-table-column>
<el-table-column label="用户名" show-overflow-tooltip minWidth="100">
<template slot-scope="scope">
<span>{{ scope.row.username }}</span>
</template>
</el-table-column>
<el-table-column label="姓名" show-overflow-tooltip minWidth="80">
<template slot-scope="scope">
<span>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="权限角色" show-overflow-tooltip minWidth="100">
<template slot-scope="scope">
<span>{{ scope.row.role || `未分配` }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="175">
<template slot-scope="scope">
<el-button
size="mini"
type="primary"
@click.stop="edit(scope.row)"
@dblclick.native.stop
>修改</el-button
>
<el-button
size="mini"
type="danger"
@click.stop="del(scope.row)"
@dblclick.native.stop
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<el-pagination
style="width: 100%; text-align: center; margin-top: 10px"
background
:hidden="total <= 10"
:layout="`total, sizes, prev, pager, next, jumper`"
:page-sizes="[10, 20, 50, 100]"
:pager-count="7"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:total="total"
@size-change="initList"
@current-change="initList"
/>
</div>
</div>
</template>
<script>
import sgSearch from "@/vue/components/admin/sgSearch";
export default {
name: "sgBody",
components: { sgSearch },
data() {
return {
ZT: 1, //当前状态
ZTs: [
{ value: 1, label: "显示文本1" },
{ value: 2, label: "显示文本2" },
{ value: 3, label: "显示文本3" },
{ value: 4, label: "显示文本4" },
{ value: 5, label: "显示文本5" },
],
fullscreenTable: false, //全屏表格
collapseSearch: false, //折叠搜索栏
sgSearchHeight: 0, //搜索栏的高度
tableData: [
{ ID: "330110198704103091", username: "username1", name: "姓名1", role: "role1" },
{ ID: "330110198704103092", username: "username2", name: "姓名2", role: "role2" },
{ ID: "330110198704103093", username: "username3", name: "姓名3", role: "role3" },
{ ID: "330110198704103094", username: "username4", name: "姓名4", role: "role4" },
{ ID: "330110198704103095", username: "username5", name: "姓名5", role: "role5" },
], //表格数据
selection: [], //表格选中项数组
currentPage: 1,
pageSize: 10,
// total: 0,
total: 999,
};
},
methods: {
row_click(row, column, event) {
this.$refs.table.toggleRowSelection(row);
},
selection_change(selection) {
this.selection = selection;
},
row_class_name({ row, rowIndex }) {
return this.selection.some((v) => v.ID === row.ID) ? "selected" : "";
},
},
};
</script>