TextArea.vue 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. <template>
  2. <textarea
  3. class="textarea"
  4. :class="{
  5. 'disabled': disabled,
  6. 'resizable': resizable,
  7. }"
  8. ref="textareaRef"
  9. :disabled="disabled"
  10. :value="value"
  11. :rows="rows"
  12. :placeholder="placeholder"
  13. :style="{
  14. padding: padding ? `${padding}px` : '10px',
  15. }"
  16. @input="$event => handleInput($event)"
  17. @focus="$event => emit('focus', $event)"
  18. @blur="$event => emit('blur', $event)"
  19. @keydown.enter="$event => emit('enter', $event)"
  20. ></textarea>
  21. </template>
  22. <script lang="ts" setup>
  23. import { useTemplateRef } from 'vue'
  24. withDefaults(defineProps<{
  25. value: string
  26. rows?: number
  27. padding?: number
  28. disabled?: boolean
  29. resizable?: boolean
  30. placeholder?: string
  31. }>(), {
  32. rows: 4,
  33. disabled: false,
  34. resizable: false,
  35. placeholder: '',
  36. })
  37. const emit = defineEmits<{
  38. (event: 'update:value', payload: string): void
  39. (event: 'focus', payload: FocusEvent): void
  40. (event: 'blur', payload: FocusEvent): void
  41. (event: 'enter', payload: KeyboardEvent): void
  42. }>()
  43. const handleInput = (e: Event) => {
  44. emit('update:value', (e.target as HTMLInputElement).value)
  45. }
  46. const textareaRef = useTemplateRef<HTMLTextAreaElement>('textareaRef')
  47. const focus = () => {
  48. if (textareaRef.value) textareaRef.value.focus()
  49. }
  50. defineExpose({
  51. focus,
  52. })
  53. </script>
  54. <style lang="scss" scoped>
  55. .textarea {
  56. outline: 0;
  57. width: 100%;
  58. background-color: #fff;
  59. border: 1px solid #d9d9d9;
  60. border-radius: $borderRadius;
  61. padding: 10px;
  62. transition: border-color .25s;
  63. box-sizing: border-box;
  64. line-height: 1.675;
  65. resize: none;
  66. font-family: -apple-system,BlinkMacSystemFont, 'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';
  67. &:focus {
  68. border-color: $themeColor;
  69. background-color: #fff;
  70. }
  71. &.resizable {
  72. resize: vertical;
  73. }
  74. &.disabled {
  75. background-color: #f5f5f5;
  76. border-color: #dcdcdc;
  77. color: #b7b7b7;
  78. }
  79. &::placeholder {
  80. color: #bfbfbf;
  81. }
  82. }
  83. </style>