app-textarea.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <template>
  2. <!-- @focus="focus" -->
  3. <div class="app">
  4. <textarea v-if="currentIsFocus" class="textarea-input" :focus="currentIsFocus" :auto-height="autoHeight" @blur="blur" @focus="focus" :disabled="disabled" @input="changeInput" :placeholder="placeholder" :maxlength="maxlength" @linechange="lineChange" :placeholder-class="placeholderClass" @confirm="confirm" v-model="currentValue"></textarea>
  5. <div v-else class="textarea-box" @click="focus">
  6. <div class="textarea-placeholder" v-if="$util.isEmpty(currentValue)">{{placeholder}}</div>
  7. <div :style="{height:autoHeight?currentHeight:'auto'}" class="textarea-dec" v-else>{{currentValue}}</div>
  8. </div>
  9. </div>
  10. </template>
  11. <script>
  12. /**
  13. * 解决textarea 层级最高问题
  14. *
  15. */
  16. export default {
  17. name: 'appTextarea', //
  18. props: {
  19. value: {
  20. type: String,
  21. default: ''
  22. },
  23. placeholder: {
  24. type: String,
  25. default: ''
  26. },
  27. maxlength: {
  28. type: Number,
  29. default: 200
  30. },
  31. autoHeight: {
  32. type: Boolean,
  33. default: true
  34. },
  35. disabled: {
  36. type: Boolean,
  37. default: false
  38. },
  39. isFocus: {
  40. type: Boolean,
  41. default: false
  42. },
  43. placeholderClass: {
  44. type: String,
  45. default: 'placeholder'
  46. }
  47. },
  48. data() {
  49. return {
  50. currentValue: '',
  51. isBlur: true,
  52. currentHeight: '',
  53. currentIsFocus: false
  54. }
  55. },
  56. created() {
  57. this.currentValue = this.$util.isEmpty(this.value) ? '' : this.value
  58. this.currentIsFocus = this.isFocus
  59. },
  60. methods: {
  61. blur() {
  62. this.currentIsFocus = false
  63. this.$emit('blur')
  64. },
  65. focus() {
  66. this.currentIsFocus = true
  67. this.$emit('focus')
  68. },
  69. changeInput(event) {
  70. this.$emit('input', event.target.value)
  71. },
  72. lineChange(val) {
  73. this.currentHeight = val.detail.height + 'px'
  74. },
  75. confirm() {
  76. this.currentIsFocus = false
  77. }
  78. },
  79. watch: {
  80. value(val) {
  81. this.currentValue = val
  82. },
  83. currentValue(val) {
  84. this.$emit('input', val)
  85. },
  86. isFocus(val) {
  87. this.currentIsFocus = val
  88. }
  89. }
  90. }
  91. </script>
  92. <style lang="scss" scoped>
  93. .app {
  94. width: 100%;
  95. height: 100%;
  96. // line-height: 1;
  97. display: inline-block;
  98. & .textarea-input {
  99. width: 100%;
  100. min-height: 36upx;
  101. height: 100%;
  102. font-size: 28upx;
  103. color: #4d4d4d;
  104. }
  105. & .textarea-box {
  106. font-size: 0;
  107. display: block;
  108. position: relative;
  109. cursor: auto;
  110. min-height: 36upx;
  111. height: 100%;
  112. width: 100%;
  113. overflow-y: auto;
  114. & .textarea-dec {
  115. font-size: 28upx;
  116. color: #4d4d4d;
  117. word-wrap: break-word;
  118. word-break: break-all;
  119. white-space: pre-wrap;
  120. // line-height: 33upx;
  121. }
  122. & .textarea-placeholder {
  123. display: inline-block;
  124. font-size: 28upx;
  125. color: #ccc;
  126. vertical-align: middle;
  127. }
  128. }
  129. }
  130. .placeholder {
  131. font-size: 28upx;
  132. color: #ccc;
  133. }
  134. </style>