ProSearch.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <script setup>
  2. import { ref, watch } from 'vue';
  3. //组件的属性
  4. let props = defineProps({
  5. form: {
  6. //表单参数详情
  7. type: Object,
  8. default: () => ({})
  9. },
  10. columns: {
  11. type: Array,
  12. default: () => []
  13. },
  14. marginBottom: {
  15. type: String,
  16. default: '10px'
  17. }
  18. });
  19. const emit = defineEmits(['update:form']);
  20. let model = ref({});
  21. watch(
  22. () => props.form,
  23. (val) => {
  24. model.value = val;
  25. },
  26. { deep: true }
  27. );
  28. watch(
  29. () => model.value,
  30. (val) => {
  31. let data = Object.assign(props.form, val);
  32. emit('update:form', data);
  33. },
  34. { deep: true }
  35. );
  36. //tag上 placeholder的显示
  37. const getPlaceholder = (row) => {
  38. if (row.placeholder) return row.placeholder;
  39. if (typeof row.tag == 'object') return;
  40. return row.label;
  41. };
  42. //插槽函数
  43. const slotFunction = (val) => {
  44. return typeof val == 'function' ? val() : val;
  45. };
  46. let formRef = ref(null);
  47. defineExpose({
  48. form: props.model
  49. });
  50. </script>
  51. <style lang="scss">
  52. .search-form {
  53. ::v-deep .el-date-editor.el-input, .el-date-editor.el-input__wrapper {
  54. width: 100%;
  55. }
  56. }
  57. </style>
  58. <template>
  59. <el-form
  60. ref="formRef"
  61. v-bind="$attrs"
  62. :labelWidth="0"
  63. :model="model"
  64. class="search-form"
  65. >
  66. <el-row :gutter="12" justify="start">
  67. <el-col
  68. v-for="element in columns"
  69. :span="element.span || 6"
  70. :key="element.prop"
  71. >
  72. <el-form-item
  73. class="custom-class"
  74. :class="element.customClass"
  75. :prop="element.prop"
  76. v-bind="element.formItemAttrs"
  77. :style="{ marginBottom: marginBottom }"
  78. >
  79. <template v-if="element.type == 'slot'">
  80. <slot
  81. :name="element.prop"
  82. :data="model"
  83. :item="element.tagAttrs"
  84. ></slot>
  85. </template>
  86. <component
  87. v-else
  88. :is="element.tag"
  89. v-bind="element.tagAttrs"
  90. v-model="model[element.prop]"
  91. :placeholder="getPlaceholder(element)"
  92. >
  93. <template v-for="(val, key, i) in element.tagSlots" :key="i" #[key]>
  94. {{ slotFunction(val) }}
  95. </template>
  96. </component>
  97. </el-form-item>
  98. </el-col>
  99. <slot></slot>
  100. </el-row>
  101. </el-form>
  102. </template>