index.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <template>
  2. <el-form
  3. :label-position="labelPosition ?? 'right'"
  4. :label-width="labelWidth ?? '120px'"
  5. :model="query"
  6. :rules="rules"
  7. ref="formRef"
  8. v-bind="$attrs"
  9. v-on="$listeners"
  10. >
  11. <template v-for="(item, _i) in items">
  12. <el-form-item
  13. v-if="!item.hidden"
  14. :key="item.prop + _i || _i"
  15. v-bind="item"
  16. >
  17. <template v-if="!item.type">
  18. <slot :name="item.prop"></slot>
  19. </template>
  20. <template v-if="item.type === 'input'">
  21. <el-input v-bind="item.options" v-on="item.handles" v-model="query[item.prop]">
  22. <template v-for="slot in item.slots" :slot="slot">
  23. <slot :name="`${item.prop}.${slot}`"></slot>
  24. </template>
  25. </el-input>
  26. </template>
  27. <template v-if="item.type === 'autocomplete'">
  28. <el-autocomplete
  29. v-model="query[item.prop]"
  30. v-bind="item.options"
  31. v-on="item.handles"
  32. >
  33. <template v-for="slot in item.slots" :slot="scope">
  34. <slot :name="`${item.prop}.${slot}`" :scope="scope"></slot>
  35. </template>
  36. </el-autocomplete>
  37. </template>
  38. <template v-if="item.type === 'number'">
  39. <el-input-number v-bind="item.options" v-on="item.handles" v-model="query[item.prop]"></el-input-number>
  40. </template>
  41. <template v-if="item.type === 'select'">
  42. <el-select v-bind="item.options" v-on="item.handles" v-model="query[item.prop]">
  43. <template v-for="slot in item.slots" :slot="slot">
  44. <slot :name="`${item.prop}.${slot}`"></slot>
  45. </template>
  46. <template v-if="item.options.groups">
  47. <el-option-group
  48. v-for="group in item.options.groups"
  49. :key="group.label"
  50. :label="group.label"
  51. >
  52. <el-option
  53. v-for="_item in group.items"
  54. :key="_item.label"
  55. v-bind="_item"
  56. >
  57. </el-option>
  58. </el-option-group>
  59. </template>
  60. <template v-else>
  61. <el-option
  62. v-for="_item in item.options.items"
  63. :key="_item.label"
  64. :label="_item[item.options.labelText ?? 'label']"
  65. :value="_item[item.options.labelValue ?? 'value']"
  66. :disable="_item.disable"
  67. ></el-option>
  68. </template>
  69. </el-select>
  70. </template>
  71. <template v-if="item.type === 'radioGroup'">
  72. <el-radio-group v-model="query[item.prop]" v-bind="item.options" v-on="item.handles">
  73. <template v-if="item.button">
  74. <el-radio-button
  75. v-for="_item in item.options.items"
  76. :key="_item.label"
  77. v-bind="_item"
  78. >
  79. {{ _item.text }}
  80. </el-radio-button>
  81. </template>
  82. <template v-else>
  83. <el-radio
  84. v-for="_item in item.options.items"
  85. :key="_item.label"
  86. v-model="query[item.prop]"
  87. v-bind="_item"
  88. >
  89. {{ _item.text }}
  90. </el-radio>
  91. </template>
  92. </el-radio-group>
  93. </template>
  94. <template v-if="item.type === 'datePicker'">
  95. <el-date-picker v-bind="item.options" v-on="item.handles" v-model="query[item.prop]"></el-date-picker>
  96. </template>
  97. <template v-if="item.type === 'cascader'">
  98. <el-cascader
  99. v-model="query[item.prop]"
  100. v-bind="item.options"
  101. v-on="item.handles"
  102. ></el-cascader>
  103. </template>
  104. <template v-if="item.slotAfter">
  105. <slot :name="`${item.prop}.after`"></slot>
  106. </template>
  107. </el-form-item>
  108. </template>
  109. <slot></slot>
  110. </el-form>
  111. </template>
  112. <script>
  113. export default {
  114. name: 'm-form',
  115. props: {
  116. labelWidth: String,
  117. labelPosition: String,
  118. value: {
  119. type: Object,
  120. default: () => {}
  121. },
  122. items: {
  123. type: Array,
  124. default: () => []
  125. }
  126. },
  127. data () {
  128. return {
  129. query: {
  130. ...this.value
  131. },
  132. rules: {}
  133. }
  134. },
  135. watch: {
  136. value: {
  137. handler (val) {
  138. this.query = val
  139. },
  140. deep: true
  141. },
  142. query: {
  143. handler (val) {
  144. this.$emit('input', val)
  145. },
  146. deep: true
  147. }
  148. },
  149. created () {
  150. this.rules = this.items.reduce((res, item) => {
  151. res[item.prop] = item.rules
  152. return res
  153. }, {})
  154. },
  155. methods: {
  156. resetFields () {
  157. this.$refs.formRef.resetFields()
  158. },
  159. clearValidate () {
  160. return this.$refs.formRef.clearValidate(...arguments)
  161. },
  162. validateField () {
  163. return this.$refs.formRef.validateField(...arguments)
  164. },
  165. validate (callback) {
  166. this.$refs.formRef.validate((valid) => {
  167. callback(valid)
  168. })
  169. }
  170. }
  171. }
  172. </script>
  173. <style lang="scss" scoped>
  174. </style>