Form.mjs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import { createVNode as _createVNode } from "vue";
  2. import { defineComponent } from "vue";
  3. import { FORM_KEY, truthProp, numericProp, preventDefault, createNamespace } from "../utils/index.mjs";
  4. import { useChildren } from "@vant/use";
  5. import { useExpose } from "../composables/use-expose.mjs";
  6. const [name, bem] = createNamespace("form");
  7. const formProps = {
  8. colon: Boolean,
  9. disabled: Boolean,
  10. readonly: Boolean,
  11. showError: Boolean,
  12. labelWidth: numericProp,
  13. labelAlign: String,
  14. inputAlign: String,
  15. scrollToError: Boolean,
  16. validateFirst: Boolean,
  17. submitOnEnter: truthProp,
  18. showErrorMessage: truthProp,
  19. errorMessageAlign: String,
  20. validateTrigger: {
  21. type: [String, Array],
  22. default: "onBlur"
  23. }
  24. };
  25. var stdin_default = defineComponent({
  26. name,
  27. props: formProps,
  28. emits: ["submit", "failed"],
  29. setup(props, {
  30. emit,
  31. slots
  32. }) {
  33. const {
  34. children,
  35. linkChildren
  36. } = useChildren(FORM_KEY);
  37. const getFieldsByNames = (names) => {
  38. if (names) {
  39. return children.filter((field) => names.includes(field.name));
  40. }
  41. return children;
  42. };
  43. const validateSeq = (names) => new Promise((resolve, reject) => {
  44. const errors = [];
  45. const fields = getFieldsByNames(names);
  46. fields.reduce((promise, field) => promise.then(() => {
  47. if (!errors.length) {
  48. return field.validate().then((error) => {
  49. if (error) {
  50. errors.push(error);
  51. }
  52. });
  53. }
  54. }), Promise.resolve()).then(() => {
  55. if (errors.length) {
  56. reject(errors);
  57. } else {
  58. resolve();
  59. }
  60. });
  61. });
  62. const validateAll = (names) => new Promise((resolve, reject) => {
  63. const fields = getFieldsByNames(names);
  64. Promise.all(fields.map((item) => item.validate())).then((errors) => {
  65. errors = errors.filter(Boolean);
  66. if (errors.length) {
  67. reject(errors);
  68. } else {
  69. resolve();
  70. }
  71. });
  72. });
  73. const validateField = (name2) => {
  74. const matched = children.find((item) => item.name === name2);
  75. if (matched) {
  76. return new Promise((resolve, reject) => {
  77. matched.validate().then((error) => {
  78. if (error) {
  79. reject(error);
  80. } else {
  81. resolve();
  82. }
  83. });
  84. });
  85. }
  86. return Promise.reject();
  87. };
  88. const validate = (name2) => {
  89. if (typeof name2 === "string") {
  90. return validateField(name2);
  91. }
  92. return props.validateFirst ? validateSeq(name2) : validateAll(name2);
  93. };
  94. const resetValidation = (name2) => {
  95. if (typeof name2 === "string") {
  96. name2 = [name2];
  97. }
  98. const fields = getFieldsByNames(name2);
  99. fields.forEach((item) => {
  100. item.resetValidation();
  101. });
  102. };
  103. const getValidationStatus = () => children.reduce((form, field) => {
  104. form[field.name] = field.getValidationStatus();
  105. return form;
  106. }, {});
  107. const scrollToField = (name2, options) => {
  108. children.some((item) => {
  109. if (item.name === name2) {
  110. item.$el.scrollIntoView(options);
  111. return true;
  112. }
  113. return false;
  114. });
  115. };
  116. const getValues = () => children.reduce((form, field) => {
  117. form[field.name] = field.formValue.value;
  118. return form;
  119. }, {});
  120. const submit = () => {
  121. const values = getValues();
  122. validate().then(() => emit("submit", values)).catch((errors) => {
  123. emit("failed", {
  124. values,
  125. errors
  126. });
  127. if (props.scrollToError && errors[0].name) {
  128. scrollToField(errors[0].name);
  129. }
  130. });
  131. };
  132. const onSubmit = (event) => {
  133. preventDefault(event);
  134. submit();
  135. };
  136. linkChildren({
  137. props
  138. });
  139. useExpose({
  140. submit,
  141. validate,
  142. getValues,
  143. scrollToField,
  144. resetValidation,
  145. getValidationStatus
  146. });
  147. return () => {
  148. var _a;
  149. return _createVNode("form", {
  150. "class": bem(),
  151. "onSubmit": onSubmit
  152. }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]);
  153. };
  154. }
  155. });
  156. export {
  157. stdin_default as default
  158. };