123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- <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: "name",
- },
- // 作为 value 唯一标识的键名,显示值
- showKey: {
- type: String,
- },
- showKey: {
- type: String,
- default: "name",
- },
- // 默认查询参数
- 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: "",
- // 选中data
- data: [],
- };
- },
- computed: {
- showValue() {
- const { showKey, valueKey } = this.$props;
- return this.data.length === 1 ? this.data[0][showKey || valueKey] : "";
- },
- },
- watch: {
- "$props.value": {
- handler: function (newProp, oldProp) {
- if (!newProp) {
- this.data = [];
- }
- },
- immediate: true,
- },
- },
- methods: {
- // 打开弹窗
- handleAsyncOpenDialog() {
- this.$nextTick(() => {
- const { setVisible } = this.$refs.TableDialog;
- setVisible(true);
- });
- },
- // 新增操作
- handleAdd(prop) {
- this.data = prop;
- this.handleUpdate(this.data);
- },
- // 删除操作
- handleDelete(prop) {
- this.data.splice(prop, 1);
- this.handleUpdate(this.data);
- },
- // 更新操作
- handleUpdate(prop) {
- const { source, multiple, valueKey, dataMapping } = this.$props;
- console.log(this.$props, 'this.$props');
- // 多选
- if (multiple) {
- const updateData = prop.map((item) => item[valueKey]);
- this.$emit("input", updateData);
- }
- // 单选
- if (!multiple) {
- const updateData = prop[0][valueKey];
- this.$emit("input", updateData);
- // 更新映射数据
- for (let key in dataMapping) {
- source[key] = prop[0][dataMapping[key]];
- console.log(source[key]);
- console.log(prop[0][dataMapping[key]]);
- }
- console.log("prop", prop, source, this.$props);
- 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 style="
- position: absolute;
- left: 10px;
- top: 50%;
- transform: translateY(-50%);
- padding-right: 30px;
- overflow: hidden;
- ">
- <div v-if="multiple && data.length > 1">
- <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',
- justifyContent: 'space-between',
- alignItems: 'center',
- margin: data.length - 1 === index ? '0' : '0 0 5px 0',
- }"
- @close="handleDelete(index)"
- >
- {{ item[showKey || valueKey] }}
- </el-tag>
- </el-popover>
- </div>
- </div>
- <table-dialog v-model="data" ref="TableDialog" :type="type" :title="title" :multiple="multiple"
- :queryParams="queryParams" @confirm="handleAdd"></table-dialog>
- </div>
- </template>
- <style scoped></style>
|