| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- <!--
- * @Descripttion: 表格选择器组件
- * @version: 1.3
- * @Author: sakuya
- * @Date: 2021年6月10日10:04:07
- * @LastEditors: sakuya
- * @LastEditTime: 2022年6月6日21:50:36
- -->
- <template>
- <el-select ref="select" v-model="defaultValue" :size="size" :clearable="clearable" :multiple="multiple" :collapse-tags="collapseTags" :collapse-tags-tooltip="collapseTagsTooltip" :placeholder="placeholder" :disabled="disabled" :placement="placement" @remove-tag="removeTag" @visible-change="visibleChange" @clear="clear">
- <template #empty>
- <div class="sc-table-select__table" :style="{ width: tableWidth + 'px' }" v-loading="loading">
- <div class="sc-table-select__header">
- <slot name="header" :queryForm="formData" :submit="formSubmit"></slot>
- </div>
- <el-table :class="!multiple && highlightCurrent && 'table-row-cursor'" ref="table" :data="tableData" :height="245" :highlight-current-row="!multiple && highlightCurrent" @row-click="click" @select="select" @select-all="selectAll">
- <el-table-column v-if="multiple" type="selection" width="45"></el-table-column>
- <el-table-column v-else type="index" width="60">
- <template #default="scope"><span>{{ scope.$index + (currentPage - 1) * pageSize + 1 }}</span></template>
- </el-table-column>
- <slot></slot>
- </el-table>
- <div v-if="!hidePagination" class="sc-table-select__page">
- <el-pagination small background :layout="paginationLayout" :total="total" :page-size="pageSize" :page-sizes="pageSizes" v-model:currentPage="currentPage" @current-change="getData" @update:page-size="pageSizeChange"></el-pagination>
- </div>
- </div>
- </template>
- </el-select>
- </template>
- <script>
- import config from "@/config/tableSelect";
- export default {
- props: {
- modelValue: null,
- apiObj: { type: Object, default: () => {} },
- apiKey: { type: String, default: "get" },
- params: { type: Object, default: () => {} },
- filters: { type: Object, default: () => {} },
- placeholder: { type: String, default: "请选择" },
- size: { type: String, default: "default" },
- clearable: { type: Boolean, default: false },
- multiple: { type: Boolean, default: false },
- collapseTags: { type: Boolean, default: false },
- collapseTagsTooltip: { type: Boolean, default: false },
- disabled: { type: Boolean, default: false },
- placement: { type: String, default: "bottom-start" },
- tableWidth: { type: Number, default: 400},
- props: { type: Object, default: () => {} },
- highlightCurrent: { type: Boolean, default: true },
- hidePagination: { type: Boolean, default: false },
- pageSizes: { type: Array, default: () => config.pageSizes },
- paginationLayout: { type: String, default: config.paginationLayout },
- applySql: { type: Boolean, default: false }
- },
- data() {
- return {
- loading: false,
- defaultValue: [],
- tableData: [],
- allTableData: [],
- pageSize: config.pageSize,
- total: 0,
- currentPage: 1,
- defaultProps: {
- label: config.props.label,
- value: config.props.value,
- page: config.request.page,
- pageSize: config.request.pageSize
- },
- formData: {}
- }
- },
- watch: {
- modelValue: {
- deep: true,
- handler() {
- this.defaultValue = this.modelValue
- this.autoCurrentLabel()
- }
- },
- apiKey() {
- this.getData()
- }
- },
- mounted() {
- this.defaultProps = Object.assign(this.defaultProps, this.props);
- this.defaultValue = this.modelValue;
- this.autoCurrentLabel();
- },
- methods: {
- //表格显示隐藏回调
- visibleChange(visible) {
- if (visible) {
- this.currentPage = 1
- this.formData = {}
- this.getData()
- } else {
- this.autoCurrentLabel()
- this.$emit("resetFilter");
- }
- },
- //获取表格数据
- async getData() {
- try {
- this.loading = true;
- const reqData = {
- [this.defaultProps.page]: this.defaultProps.page == "page" ? this.currentPage - 1 : this.currentPage,
- [this.defaultProps.pageSize]: this.pageSize
- }
- if (this.hidePagination) {
- delete reqData[this.defaultProps.page]
- delete reqData[this.defaultProps.pageSize]
- }
- if (this.applySql && this.$TOOL.data.get("APPLY_SQL")) reqData["applySql"] = this.$TOOL.data.get("APPLY_SQL");
-
- Object.assign(reqData, this.params, this.formData)
- const res = await this.apiObj[this.apiKey](reqData);
- const parseData = config.parseData(res);
- this.tableData = parseData.data || [];
- if (this.hidePagination) {
- this.allTableData = parseData.data || [];
- this.formFilter();
- }
- this.total = parseInt(parseData.total) || 0;
- this.loading = false;
-
- //表格默认赋值
- if (this.defaultValue) {
- this.$nextTick(() => {
- if (this.multiple) {
- this.defaultValue.forEach(row => {
- var setrow = this.tableData.filter(item => item[this.defaultProps.value] === row[this.defaultProps.value] )
- if (setrow.length > 0) {
- this.$refs.table.toggleRowSelection(setrow[0], true);
- }
- })
- } else {
- var setrow = this.tableData.filter(item => item[this.defaultProps.value] === this.defaultValue[this.defaultProps.value] )
- this.$refs.table.setCurrentRow(setrow[0]);
- }
- this.$refs.table.setScrollTop(0)
- })
- }
- } catch (error) {
- this.loading = false;
- }
- },
- //插糟表单提交
- formSubmit() {
- this.currentPage = 1
- this.getData()
- },
- //插糟表单筛选
- formFilter() {
- let array = this.allTableData.slice();
- for (const key in this.filters) {
- if (this.filters[key]) array = array.filter(a => a[key] && a[key].includes(this.filters[key]));
- }
- this.tableData = array.slice();
- },
- //条数变化
- pageSizeChange(size) {
- this.pageSize = size
- this.getData()
- },
- autoCurrentLabel() {
- this.$nextTick(() => {
- if (this.multiple) {
- this.$refs.select.states.selected.forEach(item => item.currentLabel = item.value[this.defaultProps.label])
- } else {
- if (this.defaultValue) this.$refs.select.states.selectedLabel = this.defaultValue[this.defaultProps.label]
- }
- })
- },
- //表格勾选事件
- select(rows, row) {
- var isSelect = rows.length && rows.indexOf(row) !== -1
- if (isSelect) {
- this.defaultValue.push(row)
- } else {
- this.defaultValue.splice(this.defaultValue.findIndex(item => item[this.defaultProps.value] == row[this.defaultProps.value]), 1)
- }
- this.autoCurrentLabel()
- this.$emit("update:modelValue", this.defaultValue);
- this.$emit("change", this.defaultValue);
- },
- //表格全选事件
- selectAll(rows) {
- var isAllSelect = rows.length > 0
- if (isAllSelect) {
- rows.forEach(row => {
- var isHas = this.defaultValue.find(item => item[this.defaultProps.value] == row[this.defaultProps.value])
- if(!isHas){
- this.defaultValue.push(row)
- }
- })
- } else {
- this.tableData.forEach(row => {
- var isHas = this.defaultValue.find(item => item[this.defaultProps.value] == row[this.defaultProps.value])
- if(isHas){
- this.defaultValue.splice(this.defaultValue.findIndex(item => item[this.defaultProps.value] == row[this.defaultProps.value]), 1)
- }
- })
- }
- this.autoCurrentLabel()
- this.$emit("update:modelValue", this.defaultValue);
- this.$emit("change", this.defaultValue);
- },
- click(row) {
- if (this.highlightCurrent) {
- if (this.multiple) {
- //处理多选点击行
- } else{
- this.defaultValue = row;
- this.$refs.select.blur();
- this.autoCurrentLabel();
- this.$emit("update:modelValue", this.defaultValue);
- this.$emit("change", this.defaultValue);
- }
- }
- },
- //tags删除后回调
- removeTag(tag){
- var row = this.findRowByKey(tag[this.defaultProps.value])
- this.$refs.table.toggleRowSelection(row, false);
- this.$emit("update:modelValue", this.defaultValue);
- },
- //清空后的回调
- clear(){
- this.$emit("update:modelValue", this.defaultValue);
- },
- // 关键值查询表格数据行
- findRowByKey (value) {
- return this.tableData.find(item => item[this.defaultProps.value] === value)
- },
- // 触发select隐藏
- blur(){
- this.$refs.select.blur();
- },
- // 触发select显示
- focus(){
- this.$refs.select.focus();
- }
- }
- }
- </script>
- <style scoped>
- .sc-table-select__table {
- min-width: 100%;
- padding: 5px 12px;
- }
- .sc-table-select__page {
- padding-top: 12px;
- }
- .sc-table-select__header :deep(.el-form) .el-form-item {
- margin-right: 20px;
- }
- .table-row-cursor :deep(.el-table__row) {
- cursor: pointer;
- }
- </style>
|