SimpleDynamicFormControl.vue 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <template>
  2. <template v-if="show">
  3. <text
  4. v-if="formDefineItem.type === 'static-text' "
  5. class="form-static-text"
  6. :style="(params.style as any)"
  7. :class="(params.class as any)"
  8. >
  9. {{ params?.text ?? modelValue ?? null }}
  10. </text>
  11. <uni-forms-item
  12. v-else
  13. ref="formItemRef"
  14. :label="label"
  15. :name="formDefineItem.fullName"
  16. :required="Boolean(formDefineItem.rules?.length)"
  17. v-bind="formDefineItem.itemParams"
  18. >
  19. <!-- <text>fullName: {{formDefineItem.fullName}}</text> -->
  20. <template v-if="formDefineItem.type === 'text'">
  21. <uni-easyinput
  22. ref="itemRef"
  23. :modelValue="modelValue"
  24. @update:modelValue="onValueChanged"
  25. :maxlength="260"
  26. v-bind="params"
  27. />
  28. </template>
  29. <template v-else-if="formDefineItem.type === 'number'">
  30. <uni-number-box
  31. ref="itemRef"
  32. :modelValue="modelValue"
  33. @update:modelValue="onValueChanged"
  34. v-bind="params"
  35. />
  36. </template>
  37. <template v-else-if="formDefineItem.type === 'radio'">
  38. <uni-data-checkbox
  39. ref="itemRef"
  40. selectedColor="#ff8719"
  41. :modelValue="modelValue"
  42. @update:modelValue="onValueChanged"
  43. v-bind="params"
  44. />
  45. </template>
  46. <template v-else-if="formDefineItem.type === 'select'">
  47. <uni-data-select
  48. ref="itemRef"
  49. :modelValue="modelValue"
  50. @update:modelValue="onValueChanged"
  51. v-bind="params"
  52. />
  53. </template>
  54. <template v-else-if="formDefineItem.type === 'checkbox'">
  55. <uni-data-checkbox
  56. ref="itemRef"
  57. selectedColor="#ff8719"
  58. :modelValue="modelValue"
  59. @update:modelValue="onValueChanged"
  60. v-bind="params"
  61. />
  62. </template>
  63. <template v-else-if="formDefineItem.type === 'bool-checkbox'">
  64. <uni-data-checkbox
  65. ref="itemRef"
  66. selectedColor="#ff8719"
  67. :modelValue="modelValue"
  68. :multiple="false"
  69. :localdata="[{text: '是', value: true}, {text: '否', value: false}]"
  70. @update:modelValue="onValueChanged"
  71. v-bind="params"
  72. />
  73. </template>
  74. <template v-else-if="formDefineItem.type === 'boolint-checkbox'">
  75. <uni-data-checkbox
  76. ref="itemRef"
  77. selectedColor="#ff8719"
  78. :modelValue="modelValue"
  79. :multiple="false"
  80. :localdata="[{text: '是', value: 1}, {text: '否', value: 0}]"
  81. @update:modelValue="onValueChanged"
  82. v-bind="params"
  83. />
  84. </template>
  85. <template v-else-if="formDefineItem.type === 'dynamic-checkbox'">
  86. <DynamicCheckbox
  87. ref="itemRef"
  88. :modelValue="modelValue"
  89. @update:modelValue="onValueChanged"
  90. v-bind="params"
  91. />
  92. </template>
  93. <template v-else-if="formDefineItem.type === 'dynamic-select'">
  94. <DynamicSelect
  95. ref="itemRef"
  96. :modelValue="modelValue"
  97. @update:modelValue="onValueChanged"
  98. v-bind="params"
  99. />
  100. </template>
  101. <template v-else-if="formDefineItem.type === 'city-select'">
  102. <CityPicker
  103. ref="itemRef"
  104. :modelValue="modelValue"
  105. @update:modelValue="onValueChanged"
  106. v-bind="params"
  107. />
  108. </template>
  109. <template v-else-if="formDefineItem.type === 'picker'">
  110. <uni-data-picker
  111. ref="itemRef"
  112. :modelValue="modelValue"
  113. @update:modelValue="onValueChanged"
  114. v-bind="params"
  115. />
  116. </template>
  117. <template v-else-if="formDefineItem.type === 'lonlat-picker'">
  118. <LonlatPicker
  119. ref="itemRef"
  120. :modelValue="modelValue"
  121. @update:modelValue="(v:any) =>{onValueChanged(v);formItemRef.onFieldChange(v)}"
  122. v-bind="params"
  123. />
  124. </template>
  125. <template v-else-if="formDefineItem.type === 'textarea'">
  126. <uni-easyinput
  127. ref="itemRef"
  128. type="textarea"
  129. :modelValue="modelValue"
  130. @update:modelValue="onValueChanged"
  131. v-bind="params"
  132. />
  133. </template>
  134. <template v-else-if="formDefineItem.type === 'richtext'">
  135. <RichTextEditor
  136. ref="itemRef"
  137. :modelValue="modelValue"
  138. @update:modelValue="onValueChanged"
  139. v-bind="params"
  140. />
  141. </template>
  142. <template v-else-if="formDefineItem.type === 'datetime-picker'">
  143. <uni-datetime-picker
  144. ref="itemRef"
  145. :value="modelValue"
  146. v-bind="params"
  147. @change="(e: any) => onValueChanged(e)"
  148. />
  149. </template>
  150. <!-- More components can be added here... -->
  151. <template v-else>
  152. <text>Fallback: unknow form type {{ formDefineItem.type }}</text>
  153. </template>
  154. </uni-forms-item>
  155. </template>
  156. </template>
  157. <script setup lang="ts">
  158. import { computed, inject, onBeforeUnmount, onMounted, ref, type PropType } from 'vue';
  159. import type { FormDefineItem, IFormItemCallback } from '.';
  160. import DynamicSelect from './components/DynamicSelect.vue';
  161. import CityPicker from './components/CityPicker.vue';
  162. import LonlatPicker from './components/LonlatPicker.vue';
  163. import DynamicCheckbox from './components/DynamicCheckbox.vue';
  164. import RichTextEditor from './components/RichTextEditor.vue';
  165. const props = defineProps({
  166. parentModel: {
  167. type: null, //TODO: parentModel
  168. },
  169. modelValue: {
  170. type: null
  171. },
  172. formDefineItem: {
  173. type: Object as PropType<FormDefineItem>,
  174. default: () => ({})
  175. },
  176. });
  177. const formItemRef = ref();
  178. const topModel = inject<any>('formTopModel', {});
  179. const formGlobalParams = inject<any>('formGlobalParams', {});
  180. function evaluateCallback(val: unknown|IFormItemCallback<unknown>) {
  181. if (typeof val === 'object' && typeof (val as IFormItemCallback<unknown>).callback === 'function')
  182. return (val as IFormItemCallback<unknown>).callback(
  183. props.modelValue,
  184. topModel.value,
  185. props.parentModel,
  186. formGlobalParams.value,
  187. props.formDefineItem,
  188. );
  189. return val as unknown;
  190. }
  191. function evaluateCallbackObj(val: Record<string, unknown|IFormItemCallback<unknown>>) {
  192. const newObj = {} as Record<string, unknown>;
  193. for (const key in val) {
  194. if (Object.prototype.hasOwnProperty.call(val, key))
  195. newObj[key] = evaluateCallback(val[key]);
  196. }
  197. return newObj;
  198. }
  199. const params = computed(() => evaluateCallbackObj(props.formDefineItem.params as any))
  200. const label = computed(() => evaluateCallback(props.formDefineItem.label))
  201. const show = computed(() => props.formDefineItem.show == undefined || evaluateCallback(props.formDefineItem.show))
  202. const itemRef = ref();
  203. const emit = defineEmits([ 'update:modelValue' ]);
  204. function onValueChanged(v: any) {
  205. props.formDefineItem.onChange?.(props.modelValue, v, topModel.value, itemRef.value);
  206. emit('update:modelValue', v);
  207. }
  208. onMounted(() => {
  209. props.formDefineItem.onMounted?.(topModel.value, itemRef.value);
  210. })
  211. onBeforeUnmount(() => {
  212. props.formDefineItem.onBeforeUnMount?.(topModel.value, itemRef.value);
  213. })
  214. </script>