textarea.uvue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <script>
  2. import { ItemType } from '@/components/enum-data/enum-data-types'
  3. export default {
  4. data() {
  5. return {
  6. adjust_position_boolean: false,
  7. show_confirm_bar_boolean: false,
  8. fixed_boolean: false,
  9. auto_height_boolean: false,
  10. confirm_hold_boolean: false,
  11. focus_boolean: true,
  12. auto_focus_boolean: false,
  13. default_value: "1\n2\n3\n4\n5\n6",
  14. inputmode_enum: [{ "value": 1, "name": "text" }, { "value": 2, "name": "decimal" }, { "value": 3, "name": "numeric" }, { "value": 4, "name": "tel" }, { "value": 5, "name": "search" }, { "value": 6, "name": "email" }, { "value": 7, "name": "url" }, { "value": 0, "name": "none" }] as ItemType[],
  15. confirm_type_list: [{ "value": 0, "name": "return" }, { "value": 1, "name": "done" }, { "value": 2, "name": "send" }, { "value": 3, "name": "search" }, { "value": 4, "name": "next" }, { "value": 5, "name": "go" }] as ItemType[],
  16. cursor_color: "#3393E2",
  17. cursor: 0,
  18. inputmode_enum_current: 0,
  19. confirm_type_current: 0,
  20. placeholder_value: "请输入",
  21. defaultModel: '123',
  22. textareaMaxLengthValue: "",
  23. isSelectionFocus: false,
  24. selectionStart: -1,
  25. selectionEnd: -1,
  26. hold_keyboard: false,
  27. adjust_position: false,
  28. disabled: false,
  29. jest_result: false,
  30. isAutoTest: false,
  31. changeValue: "",
  32. textareaRect: null as DOMRect | null,
  33. }
  34. },
  35. // #ifdef APP
  36. onReady() {
  37. const textarea = uni.getElementById("uni-textarea")
  38. this.textareaRect = textarea?.getBoundingClientRect()
  39. // 加上导航栏及状态栏高度
  40. this.textareaRect!.y += uni.getSystemInfoSync().safeArea.top + 44
  41. },
  42. // #endif
  43. methods: {
  44. textarea_click() { console.log("组件被点击时触发") },
  45. textarea_touchstart() { console.log("手指触摸动作开始") },
  46. textarea_touchmove() { console.log("手指触摸后移动") },
  47. textarea_touchcancel() { console.log("手指触摸动作被打断,如来电提醒,弹窗") },
  48. textarea_touchend() { console.log("手指触摸动作结束") },
  49. textarea_tap() { console.log("手指触摸后马上离开") },
  50. textarea_longpress() { console.log("如果一个组件被绑定了 longpress 事件,那么当用户长按这个组件时,该事件将会被触发。") },
  51. textarea_confirm() { console.log("点击完成时, 触发 confirm 事件,event.detail = {value: value}") },
  52. textarea_input(e: UniInputEvent) {
  53. console.log("当键盘输入时,触发 input 事件,event.detail = {value, cursor}, @input 处理函数的返回值并不会反映到 textarea 上")
  54. // #ifdef WEB
  55. this.jest_result = e.detail.value == '11\n2\n3\n4\n5\n6'
  56. // #endif
  57. // #ifdef APP
  58. this.jest_result = e.detail.value == '1\n2\n3\n4\n5\n61'
  59. // #endif
  60. },
  61. textarea_linechange() { console.log("输入框行数变化时调用,event.detail = {height: 0, height: 0, lineCount: 0}") },
  62. textarea_blur() { console.log("输入框失去焦点时触发,event.detail = {value, cursor}") },
  63. textarea_keyboardheightchange() { console.log("键盘高度发生变化的时候触发此事件,event.detail = {height: height, duration: duration}") },
  64. textarea_focus(event: UniTextareaFocusEvent) {
  65. this.jest_result = event.detail.height >= 0
  66. },
  67. textarea_change(event: UniInputChangeEvent) {
  68. console.log("textarea_change", event.detail.value);
  69. this.changeValue = event.detail.value
  70. },
  71. change_adjust_position_boolean(checked : boolean) { this.adjust_position_boolean = checked },
  72. change_show_confirm_bar_boolean(checked : boolean) { this.show_confirm_bar_boolean = checked },
  73. change_fixed_boolean(checked : boolean) { this.fixed_boolean = checked },
  74. change_auto_height_boolean(checked : boolean) { this.auto_height_boolean = checked },
  75. change_confirm_hold_boolean(checked : boolean) { this.confirm_hold_boolean = checked },
  76. change_focus_boolean(checked : boolean) { this.focus_boolean = checked },
  77. change_auto_focus_boolean(checked : boolean) { this.auto_focus_boolean = checked },
  78. change_cursor_color_boolean(checked : boolean) { if (checked) { this.cursor_color = "transparent" } else { this.cursor_color = "#3393E2" } },
  79. radio_change_inputmode_enum(checked : number) { this.inputmode_enum_current = checked },
  80. radio_change_confirm_type(checked : number) { this.confirm_type_current = checked },
  81. setSelection: function (selectionStart : number, selectionEnd : number) {
  82. this.isSelectionFocus = true;
  83. this.selectionStart = selectionStart;
  84. this.selectionEnd = selectionEnd;
  85. },
  86. onSelectionBlurChange() {
  87. this.isSelectionFocus = false;
  88. this.selectionEnd = 0;
  89. },
  90. changeHoldKeyboard(event : UniSwitchChangeEvent) {
  91. const checked = event.detail.value;
  92. this.hold_keyboard = checked;
  93. },
  94. changeAdjustPosition(event : UniSwitchChangeEvent) {
  95. const checked = event.detail.value;
  96. this.adjust_position = checked;
  97. },
  98. change_disabled_boolean(checked : boolean) {
  99. this.disabled = checked
  100. },
  101. getBoundingClientRectForTest() : DOMRect | null {
  102. return uni.getElementById('test-width')?.getBoundingClientRect();
  103. }
  104. }
  105. }
  106. </script>
  107. <template>
  108. <!-- #ifdef APP -->
  109. <scroll-view style="flex: 1">
  110. <!-- #endif -->
  111. <view class="main">
  112. <textarea :value="default_value" id="uni-textarea" class="uni-textarea" :auto-focus="true" :focus="focus_boolean"
  113. :confirm-hold="confirm_hold_boolean" :auto-height="auto_height_boolean" :fixed="fixed_boolean"
  114. :show-confirm-bar="show_confirm_bar_boolean" :adjust-position="adjust_position_boolean"
  115. :cursor-color="cursor_color" :cursor="cursor" :placeholder="placeholder_value"
  116. :inputmode="inputmode_enum[inputmode_enum_current].name"
  117. :confirm-type="confirm_type_list[confirm_type_current].name" :disabled="disabled" @click="textarea_click"
  118. @touchstart="textarea_touchstart" @touchmove="textarea_touchmove" @touchcancel="textarea_touchcancel"
  119. @touchend="textarea_touchend" @tap="textarea_tap" @longpress="textarea_longpress" @confirm="textarea_confirm"
  120. @input="textarea_input" @linechange="textarea_linechange" @blur="textarea_blur"
  121. @keyboardheightchange="textarea_keyboardheightchange" @focus="textarea_focus" @change="textarea_change"
  122. style="padding: 10px; border: 1px solid #666;height: 200px" />
  123. </view>
  124. <view style="margin-bottom: 40px;">
  125. <boolean-data :defaultValue="false" title="键盘弹起时,是否自动上推页面(限非 Web 平台)"
  126. @change="change_adjust_position_boolean"></boolean-data>
  127. <boolean-data :defaultValue="false" title="是否自动增高,设置auto-height时,style.height不生效"
  128. @change="change_auto_height_boolean"></boolean-data>
  129. <boolean-data :defaultValue="focus_boolean" title="获取焦点" @change="change_focus_boolean"></boolean-data>
  130. <boolean-data :defaultValue="true" title="首次自动获取焦点" @change="change_auto_focus_boolean"></boolean-data>
  131. <boolean-data :defaultValue="false" title="改变光标颜色为透明" @change="change_cursor_color_boolean"></boolean-data>
  132. <boolean-data :defaultValue="false" title="设置禁用输入框"
  133. @change="change_disabled_boolean"></boolean-data>
  134. <enum-data :items="confirm_type_list" title="confirm-type,设置键盘右下角按钮。(Android仅支持return)"
  135. @change="radio_change_confirm_type"></enum-data>
  136. <boolean-data :defaultValue="false" title="点击软键盘右下角按钮时是否保持键盘不收起(confirm-type为return时必然不收起)"
  137. @change="change_confirm_hold_boolean"></boolean-data>
  138. <enum-data :items="inputmode_enum" title="input-mode,控制软键盘类型。(仅限 Web 平台符合条件的高版本浏览器或webview)。"
  139. @change="radio_change_inputmode_enum"></enum-data>
  140. <boolean-data :defaultValue="false" title="是否显示键盘上方带有“完成”按钮那一栏(仅限小程序平台)"
  141. @change="change_show_confirm_bar_boolean"></boolean-data>
  142. <boolean-data :defaultValue="false" title="如果 textarea 是在一个 position:fixed 的区域,需要显示指定属性 fixed 为 true(仅限小程序平台)"
  143. @change="change_fixed_boolean"></boolean-data>
  144. <view class="title-wrap">
  145. <view>maxlength 输入最大长度为10</view>
  146. </view>
  147. <view class="textarea-wrap">
  148. <textarea id="textarea-instance-maxlength" class="textarea-instance" :value="textareaMaxLengthValue"
  149. :maxlength="10" />
  150. </view>
  151. <view class="title-wrap">
  152. <view>cursor-spacing、placeholder-class、placeholder-style例子(harmony 不支持设置 placeholder backgroundColor)</view>
  153. </view>
  154. <view class="textarea-wrap">
  155. <textarea id="textarea-height-exception" class="textarea-instance" placeholder="底部textarea测试键盘遮挡"
  156. placeholder-class="placeholder" placeholder-style="background-color:red" :cursor-spacing="300" />
  157. </view>
  158. <view class="title-wrap">
  159. <view @click="setSelection(2, 5)">设置输入框聚焦时光标的起始位置和结束位置(点击生效)</view>
  160. </view>
  161. <view class="textarea-wrap">
  162. <textarea id="textarea-instance-2" class="textarea-instance" value="Hello UniApp X Textarea TestCase" :focus="isSelectionFocus"
  163. :selection-start="selectionStart" :selection-end="selectionEnd" @blur="onSelectionBlurChange" />
  164. </view>
  165. <view class="title-wrap">
  166. <view>设置hold-keyboard</view>
  167. <switch style="margin-left: 10px;" @change="changeHoldKeyboard" :checked="hold_keyboard"></switch>
  168. </view>
  169. <view class="textarea-wrap">
  170. <textarea class="textarea-instance" :hold-keyboard="hold_keyboard" />
  171. </view>
  172. <view class="title-wrap">
  173. <view>同时存在 v-model 和 value</view>
  174. </view>
  175. <!-- harmony 不符合预期因为 switch 组件存在时,textarea 非预期 update 导致 -->
  176. <view class="textarea-wrap">
  177. <textarea id="both-model-value" class="textarea-instance" v-model='defaultModel' value='456'></textarea>
  178. </view>
  179. <view class="title-wrap">
  180. <view>设置adjust-position</view>
  181. <switch style="margin-left: 10px;" @change="changeAdjustPosition" :checked="adjust_position"></switch>
  182. </view>
  183. <view class="textarea-wrap">
  184. <textarea class="textarea-instance" :adjust-position="adjust_position" />
  185. </view>
  186. <view v-if="isAutoTest" class="textarea-wrap">
  187. <textarea id="test-width" class="test-width" value="123456" placeholder="" />
  188. </view>
  189. <view class="title-wrap">
  190. <view>设置line-height</view>
  191. </view>
  192. <view class="textarea-wrap">
  193. <textarea class="textarea-instance" style="line-height: 1.2em;" value="设置line-height为1.2em" ></textarea>
  194. </view>
  195. <view class="title-wrap">
  196. <view>设置max-height与auto-height</view>
  197. </view>
  198. <view class="textarea-wrap">
  199. <textarea class="textarea-instance" style="max-height: 50px;" auto-height="true" :value="default_value"></textarea>
  200. </view>
  201. </view>
  202. <!-- #ifdef APP -->
  203. </scroll-view>
  204. <!-- #endif -->
  205. </template>
  206. <style>
  207. .main {
  208. min-height: 100px;
  209. padding: 5px 0;
  210. border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  211. flex-direction: row;
  212. justify-content: center;
  213. }
  214. .test-width {
  215. width: 100px;
  216. height: 100px;
  217. background-color: aqua;
  218. }
  219. .textarea-wrap {
  220. flex-direction: row;
  221. justify-content: center;
  222. }
  223. .title-wrap {
  224. flex-direction: row;
  225. align-items: center;
  226. margin-left: 10px;
  227. }
  228. .textarea-instance {
  229. flex: 1;
  230. border: 1 solid #666;
  231. margin: 10px;
  232. }
  233. .placeholder {
  234. background-color: yellow;
  235. }
  236. </style>