Input.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import _mergeJSXProps from 'babel-helper-vue-jsx-merge-props';
  2. import _extends from 'babel-runtime/helpers/extends';
  3. import _defineProperty from 'babel-runtime/helpers/defineProperty';
  4. import classNames from 'classnames';
  5. import TextArea from './TextArea';
  6. import omit from 'omit.js';
  7. import inputProps from './inputProps';
  8. import { hasProp, getComponentFromProp, getListeners, getOptionProps } from '../_util/props-util';
  9. import { ConfigConsumerProps } from '../config-provider/configConsumerProps';
  10. import ClearableLabeledInput from './ClearableLabeledInput';
  11. function noop() {}
  12. export function fixControlledValue(value) {
  13. if (typeof value === 'undefined' || value === null) {
  14. return '';
  15. }
  16. return value;
  17. }
  18. export function resolveOnChange(target, e, onChange) {
  19. if (onChange) {
  20. var event = e;
  21. if (e.type === 'click') {
  22. // click clear icon
  23. //event = Object.create(e);
  24. Object.defineProperty(event, 'target', {
  25. writable: true
  26. });
  27. Object.defineProperty(event, 'currentTarget', {
  28. writable: true
  29. });
  30. event.target = target;
  31. event.currentTarget = target;
  32. var originalInputValue = target.value;
  33. // change target ref value cause e.target.value should be '' when clear input
  34. target.value = '';
  35. onChange(event);
  36. // reset target ref value
  37. target.value = originalInputValue;
  38. return;
  39. }
  40. onChange(event);
  41. }
  42. }
  43. export function getInputClassName(prefixCls, size, disabled) {
  44. var _classNames;
  45. return classNames(prefixCls, (_classNames = {}, _defineProperty(_classNames, prefixCls + '-sm', size === 'small'), _defineProperty(_classNames, prefixCls + '-lg', size === 'large'), _defineProperty(_classNames, prefixCls + '-disabled', disabled), _classNames));
  46. }
  47. export default {
  48. name: 'AInput',
  49. inheritAttrs: false,
  50. model: {
  51. prop: 'value',
  52. event: 'change.value'
  53. },
  54. props: _extends({}, inputProps),
  55. inject: {
  56. configProvider: { 'default': function _default() {
  57. return ConfigConsumerProps;
  58. } }
  59. },
  60. data: function data() {
  61. var props = this.$props;
  62. var value = typeof props.value === 'undefined' ? props.defaultValue : props.value;
  63. return {
  64. stateValue: typeof value === 'undefined' ? '' : value
  65. };
  66. },
  67. watch: {
  68. value: function value(val) {
  69. this.stateValue = val;
  70. }
  71. },
  72. mounted: function mounted() {
  73. var _this = this;
  74. this.$nextTick(function () {
  75. if (_this.autoFocus) {
  76. _this.focus();
  77. }
  78. _this.clearPasswordValueAttribute();
  79. });
  80. },
  81. beforeDestroy: function beforeDestroy() {
  82. if (this.removePasswordTimeout) {
  83. clearTimeout(this.removePasswordTimeout);
  84. }
  85. },
  86. methods: {
  87. onBlur: function onBlur(e) {
  88. // fix this isssue: https://github.com/vueComponent/ant-design-vue/issues/3816
  89. // reference: https://github.com/vuejs/vue/issues/5847 and https://github.com/vuejs/vue/issues/8431
  90. this.$forceUpdate();
  91. var _getListeners = getListeners(this),
  92. blur = _getListeners.blur;
  93. blur && blur(e);
  94. },
  95. focus: function focus() {
  96. this.$refs.input.focus();
  97. },
  98. blur: function blur() {
  99. this.$refs.input.blur();
  100. },
  101. select: function select() {
  102. this.$refs.input.select();
  103. },
  104. setValue: function setValue(value, callback) {
  105. if (this.stateValue === value) {
  106. return;
  107. }
  108. if (!hasProp(this, 'value')) {
  109. this.stateValue = value;
  110. this.$nextTick(function () {
  111. callback && callback();
  112. });
  113. } else {
  114. // 不在严格受控
  115. // https://github.com/vueComponent/ant-design-vue/issues/2207,modal 是 新 new 实例,更新队列和当前不在同一个更新队列中
  116. // this.$forceUpdate();
  117. }
  118. },
  119. onChange: function onChange(e) {
  120. this.$emit('change.value', e.target.value);
  121. this.$emit('change', e);
  122. this.$emit('input', e);
  123. },
  124. handleReset: function handleReset(e) {
  125. var _this2 = this;
  126. this.setValue('', function () {
  127. _this2.focus();
  128. });
  129. resolveOnChange(this.$refs.input, e, this.onChange);
  130. },
  131. renderInput: function renderInput(prefixCls) {
  132. var h = this.$createElement;
  133. var otherProps = omit(this.$props, ['prefixCls', 'addonBefore', 'addonAfter', 'prefix', 'suffix', 'allowClear', 'value', 'defaultValue', 'lazy', 'size', 'inputType', 'className']);
  134. var stateValue = this.stateValue,
  135. handleKeyDown = this.handleKeyDown,
  136. handleChange = this.handleChange,
  137. size = this.size,
  138. disabled = this.disabled;
  139. var inputProps = {
  140. directives: [{ name: 'ant-input' }],
  141. domProps: {
  142. value: fixControlledValue(stateValue)
  143. },
  144. attrs: _extends({}, otherProps, this.$attrs),
  145. on: _extends({}, getListeners(this), {
  146. keydown: handleKeyDown,
  147. input: handleChange,
  148. change: noop,
  149. blur: this.onBlur
  150. }),
  151. 'class': getInputClassName(prefixCls, size, disabled),
  152. ref: 'input',
  153. key: 'ant-input'
  154. };
  155. return h('input', inputProps);
  156. },
  157. clearPasswordValueAttribute: function clearPasswordValueAttribute() {
  158. var _this3 = this;
  159. // https://github.com/ant-design/ant-design/issues/20541
  160. this.removePasswordTimeout = setTimeout(function () {
  161. if (_this3.$refs.input && _this3.$refs.input.getAttribute && _this3.$refs.input.getAttribute('type') === 'password' && _this3.$refs.input.hasAttribute('value')) {
  162. _this3.$refs.input.removeAttribute('value');
  163. }
  164. });
  165. },
  166. handleChange: function handleChange(e) {
  167. var _e$target = e.target,
  168. value = _e$target.value,
  169. composing = _e$target.composing;
  170. // https://github.com/vueComponent/ant-design-vue/issues/2203
  171. if ((e.isComposing || composing) && this.lazy || this.stateValue === value) return;
  172. this.setValue(value, this.clearPasswordValueAttribute);
  173. resolveOnChange(this.$refs.input, e, this.onChange);
  174. },
  175. handleKeyDown: function handleKeyDown(e) {
  176. if (e.keyCode === 13) {
  177. this.$emit('pressEnter', e);
  178. }
  179. this.$emit('keydown', e);
  180. }
  181. },
  182. render: function render() {
  183. var h = arguments[0];
  184. if (this.$props.type === 'textarea') {
  185. var textareaProps = {
  186. props: this.$props,
  187. attrs: this.$attrs,
  188. on: _extends({}, getListeners(this), {
  189. input: this.handleChange,
  190. keydown: this.handleKeyDown,
  191. change: noop,
  192. blur: this.onBlur
  193. })
  194. };
  195. return h(TextArea, _mergeJSXProps([textareaProps, { ref: 'input' }]));
  196. }
  197. var customizePrefixCls = this.$props.prefixCls;
  198. var stateValue = this.$data.stateValue;
  199. var getPrefixCls = this.configProvider.getPrefixCls;
  200. var prefixCls = getPrefixCls('input', customizePrefixCls);
  201. var addonAfter = getComponentFromProp(this, 'addonAfter');
  202. var addonBefore = getComponentFromProp(this, 'addonBefore');
  203. var suffix = getComponentFromProp(this, 'suffix');
  204. var prefix = getComponentFromProp(this, 'prefix');
  205. var props = {
  206. props: _extends({}, getOptionProps(this), {
  207. prefixCls: prefixCls,
  208. inputType: 'input',
  209. value: fixControlledValue(stateValue),
  210. element: this.renderInput(prefixCls),
  211. handleReset: this.handleReset,
  212. addonAfter: addonAfter,
  213. addonBefore: addonBefore,
  214. suffix: suffix,
  215. prefix: prefix
  216. }),
  217. on: getListeners(this)
  218. };
  219. return h(ClearableLabeledInput, props);
  220. }
  221. };