|
@@ -1,5 +1,6 @@
|
|
|
<script>
|
|
|
import { REFER } from "./api/index";
|
|
|
+import deepCopy from "@gby/deep-copy";
|
|
|
export default {
|
|
|
name: "PopoverSelect",
|
|
|
props: {
|
|
@@ -83,9 +84,7 @@ export default {
|
|
|
data() {
|
|
|
return {
|
|
|
width: "50%",
|
|
|
- page: { pageNum: 1, pageSize: 25, total: 0 },
|
|
|
- layout: "total, prev, pager, next, sizes, jumper",
|
|
|
- pageSizes: [25, 50, 100],
|
|
|
+ page: { pageNum: 1, pageSize: 10, total: 0 },
|
|
|
visible: false,
|
|
|
loading: false,
|
|
|
model: {
|
|
@@ -94,6 +93,7 @@ export default {
|
|
|
},
|
|
|
data: [],
|
|
|
selectData: [],
|
|
|
+ lastSelectData: [],
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
@@ -110,16 +110,21 @@ export default {
|
|
|
watch: {
|
|
|
"$props.value": {
|
|
|
handler: function (newProp) {
|
|
|
- if (!newProp) this.selectData = [];
|
|
|
+ if (!newProp) this.lastSelectData = [];
|
|
|
},
|
|
|
immediate: true,
|
|
|
},
|
|
|
},
|
|
|
methods: {
|
|
|
+ //
|
|
|
+ emitChange(prop) {
|
|
|
+ const { type, source, multiple } = this.$props;
|
|
|
+ this.$emit("change", multiple ? prop : prop[0], source, type);
|
|
|
+ },
|
|
|
// open dialog
|
|
|
async open() {
|
|
|
this.visible = true;
|
|
|
- await this.resetList();
|
|
|
+ await this.useReset();
|
|
|
},
|
|
|
// hide dialog
|
|
|
async hide() {
|
|
@@ -140,12 +145,13 @@ export default {
|
|
|
}
|
|
|
} catch (err) {
|
|
|
//
|
|
|
+ console.error(err);
|
|
|
} finally {
|
|
|
this.loading = false;
|
|
|
}
|
|
|
},
|
|
|
- // reset list
|
|
|
- async resetList() {
|
|
|
+ // reset
|
|
|
+ async useReset() {
|
|
|
const { type, source, queryParams } = this.$props;
|
|
|
this.model = {
|
|
|
type,
|
|
@@ -155,62 +161,64 @@ export default {
|
|
|
};
|
|
|
await this.fetchList(this.model, this.page);
|
|
|
},
|
|
|
- // query list
|
|
|
- async queryList() {
|
|
|
+ // query
|
|
|
+ async useQuery() {
|
|
|
await this.fetchList(this.model, this.page);
|
|
|
},
|
|
|
+ // cancel
|
|
|
+ useCancel(prop) {
|
|
|
+ const { multiple } = this.$props;
|
|
|
+ this.useUpdate(multiple ? prop : prop[0]);
|
|
|
+ this.hide();
|
|
|
+ },
|
|
|
+ // confirm
|
|
|
+ useConfirm(prop) {
|
|
|
+ const { multiple } = this.$props;
|
|
|
+ this.useUpdate(multiple ? prop : prop[0]);
|
|
|
+ this.emitChange(this.selectData);
|
|
|
+ this.lastSelectData = deepCopy(this.selectData);
|
|
|
+ this.hide();
|
|
|
+ },
|
|
|
+ // delete
|
|
|
+ useDelete(prop) {
|
|
|
+ this.selectData.splice(prop, 1);
|
|
|
+ this.useUpdate(this.selectData);
|
|
|
+ this.emitChange(this.selectData);
|
|
|
+ this.lastSelectData = deepCopy(this.selectData);
|
|
|
+ },
|
|
|
+ // update
|
|
|
+ useUpdate(prop) {
|
|
|
+ const { source, multiple, valueKey, dataMapping } = this.$props;
|
|
|
+ // update data mapping
|
|
|
+ if (multiple) {
|
|
|
+ const vModel = prop.map((item) => item[valueKey]);
|
|
|
+ this.$emit("input", vModel);
|
|
|
+ } else {
|
|
|
+ const vModel = prop[valueKey];
|
|
|
+ this.$emit("input", vModel);
|
|
|
+ for (let key in dataMapping) {
|
|
|
+ source[key] = prop[dataMapping[key]];
|
|
|
+ }
|
|
|
+ this.$emit("update:source", source);
|
|
|
+ }
|
|
|
+ },
|
|
|
// row click
|
|
|
- rowClick(prop) {
|
|
|
+ onceClick(prop) {
|
|
|
const { multiple } = this.$props;
|
|
|
// 单选
|
|
|
if (!multiple) this.$refs.multipleTable.clearSelection();
|
|
|
[prop].forEach((row) => this.$refs.multipleTable.toggleRowSelection(row));
|
|
|
},
|
|
|
// row double click
|
|
|
- async rowDblclick(prop) {
|
|
|
+ doubleClick(prop) {
|
|
|
const { multiple } = this.$props;
|
|
|
- if (!multiple) await this.confirm([prop]);
|
|
|
+ if (!multiple) this.useConfirm([prop]);
|
|
|
},
|
|
|
// selection change
|
|
|
selectionChange(prop) {
|
|
|
- this.selectData = prop;
|
|
|
- },
|
|
|
- // page size change
|
|
|
- async pageSizeChange(prop) {
|
|
|
- this.page.pageSize = prop;
|
|
|
- await this.queryList();
|
|
|
- },
|
|
|
- // page number change
|
|
|
- async pageNumberChange(prop) {
|
|
|
- this.page.pageNum = prop;
|
|
|
- await this.queryList();
|
|
|
- },
|
|
|
- // confirm
|
|
|
- async confirm(prop) {
|
|
|
- const { multiple } = this.$props;
|
|
|
- await this.hide();
|
|
|
- await this.update(multiple ? prop : prop[0]);
|
|
|
- },
|
|
|
- // delete tag
|
|
|
- deleteTag(prop) {
|
|
|
- this.selectData.splice(prop, 1);
|
|
|
- this.update(this.selectData);
|
|
|
- },
|
|
|
- // update
|
|
|
- update(prop) {
|
|
|
- const { source, multiple, valueKey, dataMapping, type } = this.$props;
|
|
|
- // update v-model
|
|
|
- const vModel = multiple
|
|
|
- ? prop.map((item) => item[valueKey])
|
|
|
- : prop[valueKey];
|
|
|
- this.$emit("input", vModel);
|
|
|
- // update data mapping
|
|
|
- for (let key in dataMapping) {
|
|
|
- source[key] = prop[dataMapping[key]];
|
|
|
+ if (prop && prop.length) {
|
|
|
+ this.selectData = prop;
|
|
|
}
|
|
|
- this.$emit("update:source", source);
|
|
|
- // emit change
|
|
|
- this.$emit("change", prop, type, source);
|
|
|
},
|
|
|
},
|
|
|
created() {},
|
|
@@ -219,7 +227,7 @@ export default {
|
|
|
};
|
|
|
</script>
|
|
|
<template>
|
|
|
- <div>
|
|
|
+ <div class="popover-select">
|
|
|
<el-input
|
|
|
v-model="innerValue"
|
|
|
:size="size"
|
|
@@ -242,7 +250,6 @@ export default {
|
|
|
:close-on-click-modal="false"
|
|
|
:close-on-press-escape="false"
|
|
|
append-to-body
|
|
|
- @close="hide"
|
|
|
>
|
|
|
<el-form
|
|
|
v-loading="loading"
|
|
@@ -254,13 +261,13 @@ export default {
|
|
|
<el-form-item prop="search">
|
|
|
<el-input
|
|
|
v-model="model.search"
|
|
|
- @change="queryList"
|
|
|
- @keydown.enter="queryList"
|
|
|
+ @change="useQuery"
|
|
|
+ @keydown.enter="useQuery"
|
|
|
>
|
|
|
</el-input>
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
- <el-button icon="el-icon-refresh" @click="resetList"></el-button>
|
|
|
+ <el-button icon="el-icon-refresh" @click="useReset"></el-button>
|
|
|
</el-form-item>
|
|
|
<el-table
|
|
|
ref="multipleTable"
|
|
@@ -269,11 +276,16 @@ export default {
|
|
|
height="45vh"
|
|
|
highlight-current-row
|
|
|
style="width: 100%; margin-bottom: 20px"
|
|
|
- @row-click="rowClick"
|
|
|
- @row-dblclick="rowDblclick"
|
|
|
+ @row-click="onceClick"
|
|
|
+ @row-dblclick="doubleClick"
|
|
|
@selection-change="selectionChange"
|
|
|
>
|
|
|
- <el-table-column width="55" type="selection" align="center">
|
|
|
+ <el-table-column
|
|
|
+ v-if="multiple"
|
|
|
+ width="55"
|
|
|
+ type="selection"
|
|
|
+ align="center"
|
|
|
+ >
|
|
|
</el-table-column>
|
|
|
<el-table-column
|
|
|
v-for="(column, index) in TableColumnTemp"
|
|
@@ -296,22 +308,20 @@ export default {
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
- <el-pagination
|
|
|
- :layout="layout"
|
|
|
+ <pagination
|
|
|
:total="page.total"
|
|
|
- :page-sizes="pageSizes"
|
|
|
- :small="size === 'mini'"
|
|
|
- :page-size="page.pageSize"
|
|
|
- :current-page="page.pageNum"
|
|
|
- background
|
|
|
- @size-change="pageSizeChange"
|
|
|
- @current-change="pageNumberChange"
|
|
|
- >
|
|
|
- </el-pagination>
|
|
|
+ :page.sync="page.pageNum"
|
|
|
+ :limit.sync="page.pageSize"
|
|
|
+ @pagination="useQuery"
|
|
|
+ />
|
|
|
</el-form>
|
|
|
<div style="margin-top: 20px; text-align: right">
|
|
|
- <el-button :size="size" @click="hide"> 取 消 </el-button>
|
|
|
- <el-button :size="size" @click="confirm(selectData)"> 确 定 </el-button>
|
|
|
+ <el-button :size="size" @click="useCancel(lastSelectData)">
|
|
|
+ 取 消
|
|
|
+ </el-button>
|
|
|
+ <el-button :size="size" @click="useConfirm(selectData)">
|
|
|
+ 确 定
|
|
|
+ </el-button>
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
<div
|
|
@@ -324,7 +334,7 @@ export default {
|
|
|
overflow: hidden;
|
|
|
"
|
|
|
>
|
|
|
- <div v-if="multiple && selectData.length">
|
|
|
+ <div v-if="multiple && lastSelectData.length">
|
|
|
<el-popover
|
|
|
:offset="-10"
|
|
|
:width="width"
|
|
@@ -335,10 +345,10 @@ export default {
|
|
|
placement="bottom-start"
|
|
|
>
|
|
|
<el-tag slot="reference" :size="size" style="margin-right: 10px">
|
|
|
- + {{ selectData.length }}
|
|
|
+ + {{ lastSelectData.length }}
|
|
|
</el-tag>
|
|
|
<el-tag
|
|
|
- v-for="(tag, index) in selectData"
|
|
|
+ v-for="(tag, index) in lastSelectData"
|
|
|
:size="size"
|
|
|
hit
|
|
|
closable
|
|
@@ -346,9 +356,9 @@ export default {
|
|
|
display: 'flex',
|
|
|
justifyContent: 'space-between',
|
|
|
alignItems: 'center',
|
|
|
- margin: selectData.length - 1 === index ? '0' : '0 0 5px 0',
|
|
|
+ margin: lastSelectData.length - 1 === index ? '0' : '0 0 5px 0',
|
|
|
}"
|
|
|
- @close="deleteTag(index)"
|
|
|
+ @close="useDelete(index)"
|
|
|
>
|
|
|
{{ tag.name }}
|
|
|
</el-tag>
|