<script> import { REFER } from "../popover-select/api/index"; export default { name: "PopoverSelectV2", props: { // v-model value: { type: [Array, String, Number], require: true, }, // 参照类型 ,对应后端 referName: { type: String, require: true, }, // 作为 value 唯一标识的键名,绑定值 valueKey: { type: String, dafault: () => { return "code"; }, }, // 默认查询参数 queryParams: { type: Function, default: () => {}, }, // 需映射源数据 source: { type: Object, default: () => ({}), }, // 参照内外映射 dataMapping: { type: Object, default: () => ({}), }, // 多选 checkbox: { type: Boolean, default: false, }, // 参照弹窗标题 title: { type: String, dafault: () => { return "TITEL"; }, }, // 赋值 copy: { type: Boolean, default: () => { return false; }, }, clearable: { type: Boolean, default: true, }, }, components: { ElSuperTable: () => import("@/components/super-table/index.vue"), }, data() { return { size: "mini", width: "50%", page: { pageNum: 1, pageSize: 10, total: 0 }, visible: false, loading: false, model: { search: "", isPage: true, }, data: [], selectData: [], }; }, computed: { innerValue: { get() { return this.value; }, set(value) { // const { // $props: { source, dataMapping }, // } = this; // for (let key in dataMapping) { // if (dataMapping[key] === "id" || dataMapping[key] === "code") { // if (source[key] && source[key] !== "") { // source[key] = undefined; // } // } // } this.$emit("input", value); }, }, TableColumns() { const { referName } = this.$props; return require(`../popover-select/components/${referName}`).default; }, }, watch: { innerValue: { handler: function (newValue) { if (!newValue) { const { $props: { source, dataMapping }, } = this; for (let key in dataMapping) { source[key] = undefined; } this.$emit("update:source", source); } }, }, }, methods: { // open dialog async open() { let { disabled } = this.$attrs; if (!disabled) { this.visible = true; await this.useReset(); } }, // hide dialog async hide() { this.visible = false; }, // fetch list async fetchList(prop, page) { try { // try this.loading = true; const { pageNum, pageSize } = page; const { referName: type, source, queryParams } = this.$props; const { code, rows, total } = await REFER( { ...prop, ...queryParams(source), type: type, }, { pageNum, pageSize, } ); if (code === 200) { this.data = rows; // 处理新增字段无法映射 let that = this; this.TableColumns.forEach(({ item, attr }) => { that.data = that.data.map((d) => { if (!attr.is && attr.formatter) { d[item.key] = attr.formatter(d); } return d; }); }); this.page.total = total; } } catch (err) { // catch console.error(err); } finally { // finally this.loading = false; } }, // reset async useReset() { this.data = []; this.page.pageNum = 1; this.page.pageSize = 10; this.model.search = null; await this.fetchList(this.model, this.page); }, // query async useQuery() { await this.fetchList(this.model, this.page); }, // auto async useAutocomplete(prop, cb) { if (prop) { this.page.pageSize = 10; this.model.search = prop; await this.fetchList(this.model, this.page); await cb(this.data); } else { cb([]); } }, // select useSelect(prop) { this.selectData = prop; }, // confirm useConfirm(prop) { this.hide(); const { $props: { source, checkbox, valueKey, dataMapping }, } = this; if (checkbox) { this.selectData = [...prop]; this.$emit( "change", this.selectData.map((item) => { for (let key in dataMapping) { item[key] = item[dataMapping[key]]; } return item; }), this.$props ); } else { for (let key in dataMapping) { source[key] = prop[0][dataMapping[key]]; } this.innerValue = prop[0][valueKey]; this.$emit("update:source", source); this.$emit("change", prop[0], this.$props); } }, async handleChange() { const { referName } = this.$props; this.$emit("copyChange", this.innerValue.split(/,|,|\s+/)); }, useBlur() { const { $props: { source, dataMapping }, } = this; for (let key in dataMapping) { if (dataMapping[key] === "id" || dataMapping[key] === "code") { if (!source[key] || source[key] === "") { this.innerValue = ""; } } } }, handleClear() { this.innerValue = ""; }, handleKeyupDel() { console.log("focus"); const { $props: { source, dataMapping }, } = this; for (let key in dataMapping) { if (dataMapping[key] === "id" || dataMapping[key] === "code") { if (source[key] && source[key] !== "") { source[key] = undefined; } } } }, }, created() {}, mounted() {}, destroyed() {}, }; </script> <template> <div class="popover-select-v2"> <el-input v-if="copy" :clearable="clearable" v-bind="$attrs" v-model="innerValue" :size="size" @clear="handleClear" @change="handleChange" @keyup.enter.native="handleChange" @keyup.delete.native="handleKeyupDel" > <i :size="size" class="el-icon-search" slot="suffix" @click="open"> </i> </el-input> <el-autocomplete v-else :clearable="clearable" v-bind="$attrs" v-model="innerValue" :value-key="valueKey" :fetch-suggestions="useAutocomplete" @blur="useBlur" @select="useConfirm([$event])" style="width: 100%" > <i class="el-icon-search" slot="suffix" @click="open"> </i> <template slot-scope="{ item }"> <p style=" text-overflow: ellipsis; overflow: hidden; line-height: 15px; margin: 5px 0; " > {{ item.name }} </p> <p style=" font-size: 12px; color: #b4b4b4; line-height: 15px; margin: 5px 0; " > {{ item.code }} </p> </template> </el-autocomplete> <el-dialog :width="width" :visible.sync="visible" :show-close="false" :close-on-click-modal="false" :close-on-press-escape="false" append-to-body > <div slot="title" style="display: flex; justify-content: space-between"> <el-form :size="size" :inline="true" :model="model" @submit.native.prevent style="display: flex; flex-direction: column" > <div> <el-form-item prop="search"> <el-input v-model="model.search" @change="useQuery" @keydown.enter="useQuery" > </el-input> </el-form-item> <el-form-item> <el-button icon="el-icon-search" @click="useQuery" >搜索</el-button > <el-button icon="el-icon-refresh" @click="useReset" >重置</el-button > </el-form-item> </div> </el-form> <div> <el-button type="primary" :size="$attrs.size" :loading="loading" @click="useConfirm(selectData)" > 确认 </el-button> <el-button :size="$attrs.size" :loading="loading" @click="hide"> 取消 </el-button> </div> </div> <div v-loading="loading" style="height: 40vh; display: flex; margin-top: -30px" > <el-super-table v-model="data" :size="size" :page="page" :columns="TableColumns" :radio="!checkbox" :checkbox="checkbox" pagination highlight-current-row @pagination="useQuery" @row-select="useSelect" @row-dblclick="useConfirm([$event])" > </el-super-table> </div> </el-dialog> </div> </template> <style scoped> .popover-select-v2 .el-autocomplete { width: inherit; } .popover-select-v2 .el-autocomplete .el-icon-search { cursor: pointer; } ::v-deep .el-table--mini .el-table__cell { height: 50px; } </style>