项目原始demo,不改动
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 

246 lines
5.9 KiB

  1. // Mixins
  2. import Colorable from '../colorable';
  3. import Themeable from '../themeable';
  4. import { inject as RegistrableInject } from '../registrable'; // Utilities
  5. import { deepEqual } from '../../util/helpers';
  6. import { consoleError } from '../../util/console';
  7. import mixins from '../../util/mixins';
  8. /* @vue/component */
  9. export default mixins(Colorable, RegistrableInject('form'), Themeable).extend({
  10. name: 'validatable',
  11. props: {
  12. disabled: Boolean,
  13. error: Boolean,
  14. errorCount: {
  15. type: [Number, String],
  16. default: 1
  17. },
  18. errorMessages: {
  19. type: [String, Array],
  20. default: () => []
  21. },
  22. messages: {
  23. type: [String, Array],
  24. default: () => []
  25. },
  26. readonly: Boolean,
  27. rules: {
  28. type: Array,
  29. default: () => []
  30. },
  31. success: Boolean,
  32. successMessages: {
  33. type: [String, Array],
  34. default: () => []
  35. },
  36. validateOnBlur: Boolean,
  37. value: {
  38. required: false
  39. }
  40. },
  41. data() {
  42. return {
  43. errorBucket: [],
  44. hasColor: false,
  45. hasFocused: false,
  46. hasInput: false,
  47. isFocused: false,
  48. isResetting: false,
  49. lazyValue: this.value,
  50. valid: false
  51. };
  52. },
  53. computed: {
  54. computedColor() {
  55. if (this.disabled) return undefined;
  56. if (this.color) return this.color; // It's assumed that if the input is on a
  57. // dark background, the user will want to
  58. // have a white color. If the entire app
  59. // is setup to be dark, then they will
  60. // like want to use their primary color
  61. if (this.isDark && !this.appIsDark) return 'white';else return 'primary';
  62. },
  63. hasError() {
  64. return this.internalErrorMessages.length > 0 || this.errorBucket.length > 0 || this.error;
  65. },
  66. // TODO: Add logic that allows the user to enable based
  67. // upon a good validation
  68. hasSuccess() {
  69. return this.internalSuccessMessages.length > 0 || this.success;
  70. },
  71. externalError() {
  72. return this.internalErrorMessages.length > 0 || this.error;
  73. },
  74. hasMessages() {
  75. return this.validationTarget.length > 0;
  76. },
  77. hasState() {
  78. if (this.disabled) return false;
  79. return this.hasSuccess || this.shouldValidate && this.hasError;
  80. },
  81. internalErrorMessages() {
  82. return this.genInternalMessages(this.errorMessages);
  83. },
  84. internalMessages() {
  85. return this.genInternalMessages(this.messages);
  86. },
  87. internalSuccessMessages() {
  88. return this.genInternalMessages(this.successMessages);
  89. },
  90. internalValue: {
  91. get() {
  92. return this.lazyValue;
  93. },
  94. set(val) {
  95. this.lazyValue = val;
  96. this.$emit('input', val);
  97. }
  98. },
  99. shouldValidate() {
  100. if (this.externalError) return true;
  101. if (this.isResetting) return false;
  102. return this.validateOnBlur ? this.hasFocused && !this.isFocused : this.hasInput || this.hasFocused;
  103. },
  104. validations() {
  105. return this.validationTarget.slice(0, Number(this.errorCount));
  106. },
  107. validationState() {
  108. if (this.disabled) return undefined;
  109. if (this.hasError && this.shouldValidate) return 'error';
  110. if (this.hasSuccess) return 'success';
  111. if (this.hasColor) return this.computedColor;
  112. return undefined;
  113. },
  114. validationTarget() {
  115. if (this.internalErrorMessages.length > 0) {
  116. return this.internalErrorMessages;
  117. } else if (this.successMessages.length > 0) {
  118. return this.internalSuccessMessages;
  119. } else if (this.messages.length > 0) {
  120. return this.internalMessages;
  121. } else if (this.shouldValidate) {
  122. return this.errorBucket;
  123. } else return [];
  124. }
  125. },
  126. watch: {
  127. rules: {
  128. handler(newVal, oldVal) {
  129. if (deepEqual(newVal, oldVal)) return;
  130. this.validate();
  131. },
  132. deep: true
  133. },
  134. internalValue() {
  135. // If it's the first time we're setting input,
  136. // mark it with hasInput
  137. this.hasInput = true;
  138. this.validateOnBlur || this.$nextTick(this.validate);
  139. },
  140. isFocused(val) {
  141. // Should not check validation
  142. // if disabled
  143. if (!val && !this.disabled) {
  144. this.hasFocused = true;
  145. this.validateOnBlur && this.$nextTick(this.validate);
  146. }
  147. },
  148. isResetting() {
  149. setTimeout(() => {
  150. this.hasInput = false;
  151. this.hasFocused = false;
  152. this.isResetting = false;
  153. this.validate();
  154. }, 0);
  155. },
  156. hasError(val) {
  157. if (this.shouldValidate) {
  158. this.$emit('update:error', val);
  159. }
  160. },
  161. value(val) {
  162. this.lazyValue = val;
  163. }
  164. },
  165. beforeMount() {
  166. this.validate();
  167. },
  168. created() {
  169. this.form && this.form.register(this);
  170. },
  171. beforeDestroy() {
  172. this.form && this.form.unregister(this);
  173. },
  174. methods: {
  175. genInternalMessages(messages) {
  176. if (!messages) return [];else if (Array.isArray(messages)) return messages;else return [messages];
  177. },
  178. /** @public */
  179. reset() {
  180. this.isResetting = true;
  181. this.internalValue = Array.isArray(this.internalValue) ? [] : undefined;
  182. },
  183. /** @public */
  184. resetValidation() {
  185. this.isResetting = true;
  186. },
  187. /** @public */
  188. validate(force = false, value) {
  189. const errorBucket = [];
  190. value = value || this.internalValue;
  191. if (force) this.hasInput = this.hasFocused = true;
  192. for (let index = 0; index < this.rules.length; index++) {
  193. const rule = this.rules[index];
  194. const valid = typeof rule === 'function' ? rule(value) : rule;
  195. if (valid === false || typeof valid === 'string') {
  196. errorBucket.push(valid || '');
  197. } else if (typeof valid !== 'boolean') {
  198. consoleError(`Rules should return a string or boolean, received '${typeof valid}' instead`, this);
  199. }
  200. }
  201. this.errorBucket = errorBucket;
  202. this.valid = errorBucket.length === 0;
  203. return this.valid;
  204. }
  205. }
  206. });
  207. //# sourceMappingURL=index.js.map