index.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. <template>
  2. <view>
  3. <sjs src="../wxs/utils.sjs" module="utils" />
  4. <van-cell
  5. :size="size"
  6. :icon="leftIcon"
  7. :title="label"
  8. :center="center"
  9. :border="border"
  10. :is-link="isLink"
  11. :required="required"
  12. :clickable="clickable"
  13. :title-width="titleWidth"
  14. :custom-style="customStyle"
  15. :arrow-direction="arrowDirection"
  16. custom-class="van-field"
  17. >
  18. <slot name="left-icon" slot="icon" />
  19. <slot name="label" slot="title" />
  20. <view :class="utils.bem('field__body', [type, system])">
  21. <textarea
  22. :wx:if="type === 'textarea'"
  23. :class="'input-class ' + utils.bem('field__input', [inputAlign, type, { disabled, error }])"
  24. :fixed="fixed"
  25. :focus="focus"
  26. :value="value"
  27. :disabled="disabled || readonly"
  28. :maxlength="maxlength"
  29. :placeholder="placeholder"
  30. :placeholder-style="placeholderStyle"
  31. :placeholder-class="utils.bem('field__placeholder', { error })"
  32. :auto-height="autosize"
  33. :cursor-spacing="cursorSpacing"
  34. :adjust-position="adjustPosition"
  35. :show-confirm-bar="showConfirmBar"
  36. :hold-keyboard="holdKeyboard"
  37. :selection-end="selectionEnd"
  38. :selection-start="selectionStart"
  39. @input="onInput"
  40. @blur="onBlur"
  41. @focus="onFocus"
  42. @confirm="onConfirm"
  43. ></textarea>
  44. <input
  45. wx:else
  46. :class="'input-class ' + utils.bem('field__input', [inputAlign, { disabled, error }])"
  47. :type="type"
  48. :focus="focus"
  49. :value="value"
  50. :disabled="disabled || readonly"
  51. :maxlength="maxlength"
  52. :placeholder="placeholder"
  53. :placeholder-style="placeholderStyle"
  54. :placeholder-class="utils.bem('field__placeholder', { error })"
  55. :confirm-type="confirmType"
  56. :confirm-hold="confirmHold"
  57. :hold-keyboard="holdKeyboard"
  58. :cursor-spacing="cursorSpacing"
  59. :adjust-position="adjustPosition"
  60. :selection-end="selectionEnd"
  61. :selection-start="selectionStart"
  62. :password="password || type === 'password'"
  63. @input="onInput"
  64. @blur="onBlur"
  65. @focus="onFocus"
  66. @confirm="onConfirm"
  67. />
  68. <van-icon
  69. :wx:if="clearable && focused && value && !readonly"
  70. size="16px"
  71. name="clear"
  72. class="van-field__clear-root van-field__icon-root"
  73. @touchstart.native="onClear"
  74. />
  75. <view class="van-field__icon-container" @tap="onClickIcon">
  76. <van-icon :wx:if="rightIcon || icon" size="16px" :name="rightIcon || icon" :class="'van-field__icon-root ' + iconClass" custom-class="right-icon-class" />
  77. <slot name="right-icon" />
  78. <slot name="icon" />
  79. </view>
  80. <view class="van-field__button"><slot name="button" /></view>
  81. </view>
  82. <view :wx:if="errorMessage" :class="'van-field__error-message ' + utils.bem('field__error', [errorMessageAlign, { disabled, error }])">{{ errorMessage }}</view>
  83. </van-cell>
  84. </view>
  85. </template>
  86. <script>
  87. import { VantComponent } from '../common/component';
  88. import { getSystemInfoSync } from '../common/utils';
  89. export default {
  90. data() {
  91. return {
  92. focused: false,
  93. system: getSystemInfoSync().system.split(' ').shift().toLowerCase(),
  94. value: ''
  95. };
  96. },
  97. field: true,
  98. classes: ['input-class', 'right-icon-class'],
  99. props: {
  100. size: String,
  101. icon: String,
  102. label: String,
  103. error: Boolean,
  104. fixed: Boolean,
  105. focus: Boolean,
  106. center: Boolean,
  107. isLink: Boolean,
  108. leftIcon: String,
  109. rightIcon: String,
  110. disabled: Boolean,
  111. autosize: Boolean,
  112. readonly: Boolean,
  113. required: Boolean,
  114. password: Boolean,
  115. iconClass: String,
  116. clearable: Boolean,
  117. clickable: Boolean,
  118. inputAlign: String,
  119. placeholder: String,
  120. customStyle: String,
  121. confirmType: String,
  122. confirmHold: Boolean,
  123. holdKeyboard: Boolean,
  124. errorMessage: String,
  125. arrowDirection: String,
  126. placeholderStyle: String,
  127. errorMessageAlign: String,
  128. selectionEnd: {
  129. type: Number,
  130. default: -1
  131. },
  132. selectionStart: {
  133. type: Number,
  134. default: -1
  135. },
  136. showConfirmBar: {
  137. type: Boolean,
  138. default: true
  139. },
  140. adjustPosition: {
  141. type: Boolean,
  142. default: true
  143. },
  144. cursorSpacing: {
  145. type: Number,
  146. default: 50
  147. },
  148. maxlength: {
  149. type: Number,
  150. default: -1
  151. },
  152. type: {
  153. type: String,
  154. default: 'text'
  155. },
  156. border: {
  157. type: Boolean,
  158. default: true
  159. },
  160. titleWidth: {
  161. type: String,
  162. default: '90px'
  163. }
  164. },
  165. methods: {
  166. onInput(event) {
  167. const { value = '' } = event.detail || {};
  168. this.setData(
  169. {
  170. value
  171. },
  172. () => {
  173. this.emitChange(value);
  174. }
  175. );
  176. },
  177. onFocus(event) {
  178. this.setData({
  179. focused: true
  180. });
  181. this.$emit('focus', event.detail);
  182. },
  183. onBlur(event) {
  184. this.setData({
  185. focused: false
  186. });
  187. this.$emit('blur', event.detail);
  188. },
  189. onClickIcon() {
  190. this.$emit('click-icon');
  191. },
  192. onClear() {
  193. this.setData(
  194. {
  195. value: ''
  196. },
  197. () => {
  198. this.emitChange('');
  199. this.$emit('clear', '');
  200. }
  201. );
  202. },
  203. onConfirm() {
  204. this.$emit('confirm', this.value);
  205. },
  206. emitChange(value) {
  207. this.$emit('input', value);
  208. this.$emit('change', value);
  209. }
  210. }
  211. };
  212. </script>
  213. <style>
  214. @import '../common/index.ttss';
  215. .van-field__body {
  216. display: -webkit-flex;
  217. display: flex;
  218. -webkit-align-items: center;
  219. align-items: center;
  220. }
  221. .van-field__body--textarea {
  222. line-height: 1.2em;
  223. min-height: 24px;
  224. min-height: var(--cell-line-height, 24px);
  225. }
  226. .van-field__body--textarea.van-field__body--ios {
  227. margin-top: -4.5px;
  228. }
  229. .van-field__input {
  230. position: relative;
  231. display: block;
  232. box-sizing: border-box;
  233. width: 100%;
  234. margin: 0;
  235. padding: 0;
  236. line-height: inherit;
  237. text-align: left;
  238. background-color: initial;
  239. border: 0;
  240. resize: none;
  241. color: #323233;
  242. color: var(--field-input-text-color, #323233);
  243. height: 24px;
  244. height: var(--cell-line-height, 24px);
  245. min-height: 24px;
  246. min-height: var(--cell-line-height, 24px);
  247. }
  248. .van-field__input--textarea {
  249. height: 18px;
  250. height: var(--field-text-area-min-height, 18px);
  251. min-height: 18px;
  252. min-height: var(--field-text-area-min-height, 18px);
  253. }
  254. .van-field__input--error {
  255. color: #ee0a24;
  256. color: var(--field-input-error-text-color, #ee0a24);
  257. }
  258. .van-field__input--disabled {
  259. background-color: initial;
  260. opacity: 1;
  261. color: #969799;
  262. color: var(--field-input-disabled-text-color, #969799);
  263. }
  264. .van-field__input--center {
  265. text-align: center;
  266. }
  267. .van-field__input--right {
  268. text-align: right;
  269. }
  270. .van-field__placeholder {
  271. position: absolute;
  272. top: 0;
  273. right: 0;
  274. left: 0;
  275. pointer-events: none;
  276. color: #969799;
  277. color: var(--field-placeholder-text-color, #969799);
  278. }
  279. .van-field__placeholder--error {
  280. color: #ee0a24;
  281. color: var(--field-error-message-color, #ee0a24);
  282. }
  283. .van-field__icon-root {
  284. display: -webkit-flex;
  285. display: flex;
  286. -webkit-align-items: center;
  287. align-items: center;
  288. min-height: 24px;
  289. min-height: var(--cell-line-height, 24px);
  290. }
  291. .van-field__clear-root,
  292. .van-field__icon-container {
  293. line-height: inherit;
  294. vertical-align: middle;
  295. padding: 0 8px;
  296. padding: 0 var(--padding-xs, 8px);
  297. margin-right: -8px;
  298. margin-right: -var(--padding-xs, 8px);
  299. }
  300. .van-field__button,
  301. .van-field__clear-root,
  302. .van-field__icon-container {
  303. -webkit-flex-shrink: 0;
  304. flex-shrink: 0;
  305. }
  306. .van-field__clear-root {
  307. color: #c8c9cc;
  308. color: var(--field-clear-icon-color, #c8c9cc);
  309. }
  310. .van-field__icon-container {
  311. color: #969799;
  312. color: var(--field-icon-container-color, #969799);
  313. }
  314. .van-field__icon-container:empty {
  315. display: none;
  316. }
  317. .van-field__button {
  318. padding-left: 8px;
  319. padding-left: var(--padding-xs, 8px);
  320. }
  321. .van-field__button:empty {
  322. display: none;
  323. }
  324. .van-field__error-message {
  325. text-align: left;
  326. font-size: 12px;
  327. font-size: var(--field-error-message-text-font-size, 12px);
  328. color: #ee0a24;
  329. color: var(--field-error-message-color, #ee0a24);
  330. }
  331. .van-field__error-message--center {
  332. text-align: center;
  333. }
  334. .van-field__error-message--right {
  335. text-align: right;
  336. }
  337. </style>