123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- <script>
- export default {
- name: "PopoverSelect",
- props: {
- // 参照类型 ,对应后端
- type: {
- type: String,
- require: true,
- },
- // v-model
- value: {
- type: [Array, String],
- require: true,
- },
- // 参照弹窗标题
- title: {
- type: String,
- default: "TITLE",
- },
- // 作为 value 唯一标识的键名,绑定值为对象类型时必填
- valueKey: {
- type: String,
- default: "id",
- },
- // 默认查询参数
- queryParams: {
- type: Object,
- default: () => ({}),
- },
- // 组件大小
- size: {
- type: String,
- default: "mini",
- },
- // 提示
- placeholder: {
- type: String,
- default: "",
- },
- // 是否可读
- readonly: {
- type: Boolean,
- default: false,
- },
- // 是否禁止
- disabled: {
- type: Boolean,
- default: false,
- },
- // 是否清除
- clearable: {
- type: Boolean,
- default: false,
- },
- // 是否多选
- multiple: {
- type: Boolean,
- default: false,
- },
- // 需映射源数据
- source: Object,
- // 参照内外映射
- dataMapping: Object,
- },
- emits: ["hide"],
- components: {
- TableDialog: () => import("./components/index.vue"),
- },
- data() {
- return {
- // popover宽度
- width: "",
- // 显示value
- showValue: "",
- // 选中data
- data: [],
- };
- },
- computed: {},
- watch: {
- "$props.value": {
- handler: function (newProp, oldProp) {
- if (!newProp) {
- this.data = [];
- this.showValue = "";
- }
- },
- immediate: true,
- },
- },
- methods: {
- // 打开弹窗
- handleAsyncOpenDialog() {
- this.$nextTick(() => {
- const { setVisible } = this.$refs.TableDialogFef;
- setVisible(true);
- });
- },
- // 新增操作
- handleAdd(prop) {
- this.data = prop;
- this.handleUpdate(this.data);
- this.$emit("hide", prop);
- },
- // 删除操作
- handleDelete(prop) {
- this.data.splice(prop, 1);
- this.handleUpdate(this.data);
- },
- // 更新操作
- handleUpdate(prop) {
- const { source, multiple, valueKey, dataMapping } = this.$props;
- // 多选
- if (multiple) {
- this.showValue = "";
- this.$emit(
- "input",
- prop.map((item) => item[valueKey])
- );
- }
- // 单选
- if (!multiple) {
- this.showValue = prop[0].name;
- this.$emit("input", prop[0][valueKey]);
- // 更新映射数据
- for (let key in dataMapping) {
- source[key] = prop[0][dataMapping[key]];
- }
- this.$emit("update:source", source);
- }
- //
- this.$emit("change", prop, source);
- },
- },
- created() {
- this.$nextTick(() => {
- const { clientWidth } = this.$refs.PopoverSelect;
- this.width = clientWidth;
- });
- },
- mounted() {},
- destroyed() {},
- };
- </script>
- <template>
- <div ref="PopoverSelect" style="position: relative">
- <el-input
- v-model="showValue"
- :size="size"
- :disabled="disabled"
- :clearable="clearable"
- :placeholder="placeholder"
- readonly
- style="width: 100%; cursor: pointer"
- @click.native.stop="handleAsyncOpenDialog"
- >
- <template #suffix>
- <el-icon class="el-icon-more"></el-icon>
- </template>
- </el-input>
- <div
- v-if="multiple && data.length"
- style="
- position: absolute;
- left: 10px;
- top: 50%;
- transform: translateY(-50%);
- padding-right: 30px;
- overflow: hidden;
- "
- >
- <div style="width: 150px; display: flex">
- <el-popover
- :offset="-10"
- :width="width"
- :visible-arrow="false"
- title=""
- content=""
- trigger="click"
- placement="bottom-start"
- >
- <el-tag slot="reference" :size="size" style="margin-right: 10px">
- + {{ data.length }}
- </el-tag>
- <el-tag
- v-for="(item, index) in data"
- :size="size"
- hit
- closable
- style="
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin: 0 0 5px 0;
- "
- @close="handleDelete(index)"
- >
- {{ item.name }}
- </el-tag>
- </el-popover>
- </div>
- </div>
- <table-dialog
- v-model="data"
- ref="TableDialogFef"
- :type="type"
- :title="title"
- :multiple="multiple"
- :queryParams="queryParams"
- @confirm="handleAdd"
- ></table-dialog>
- </div>
- </template>
- <style scoped></style>
|