1. 程式人生 > 其它 >Vue中可根據內容自適應改變高度的textarea文字框

Vue中可根據內容自適應改變高度的textarea文字框

https://www.jianshu.com/p/23c3a6d5dfdf

 

 

<template>
    <div class="my-textarea">
      <textarea ref="textarea" :style="{'height': height}" v-model="value" class="textarea" ></textarea>
    </div>
</template>

<script>
  import calcTextareaHeight from '@/assets/calcTextareaHeight';

  export default {
    name: 'my-textarea',
    data() {
      return {
        // textarea內容
        value: '',
        // 動態高度
        height: '30px'
      }
    },
    watch: {
      value() {
        this.getHeight();
      }
    },
    methods: {
      getHeight() {
        this.height = calcTextareaHeight(this.$refs.textarea, 1, null).height;
      }
    }
  }
</script>

<style scoped>
  .my-textarea .textarea {
    display: inline-block;
    width: 400px;
    /*height: 30px;*/
    line-height: 30px;
    font-size: 30px;
    resize: none;
  }
</style>







let hiddenTextarea;
const HIDDEN_STYLE = `   height:0 !important;   visibility:hidden !important;   overflow:hidden !important;   position:absolute !important;   z-index:-1000 !important;   top:0 !important;   right:0 !important `;
const CONTEXT_STYLE = [   'letter-spacing',   'line-height',   'padding-top',   'padding-bottom',   'font-family',   'font-weight',   'font-size',   'text-rendering',   'text-transform',   'width',   'text-indent',   'padding-left',   'padding-right',   'border-width',   'box-sizing' ];
function calculateNodeStyling(targetElement) {   const style = window.getComputedStyle(targetElement);
  const boxSizing = style.getPropertyValue('box-sizing');
  const paddingSize = (     parseFloat(style.getPropertyValue('padding-bottom')) +     parseFloat(style.getPropertyValue('padding-top'))   );
  const borderSize = (     parseFloat(style.getPropertyValue('border-bottom-width')) +     parseFloat(style.getPropertyValue('border-top-width'))   );
  const contextStyle = CONTEXT_STYLE     .map(name => `${name}:${style.getPropertyValue(name)}`)     .join(';');
  return { contextStyle, paddingSize, borderSize, boxSizing }; }
export default function calcTextareaHeight(   targetElement,   minRows = 1,   maxRows = null ) {   if (!hiddenTextarea) {     hiddenTextarea = document.createElement('textarea');     document.body.appendChild(hiddenTextarea);   }
  let {     paddingSize,     borderSize,     boxSizing,     contextStyle   } = calculateNodeStyling(targetElement);
  hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`);   hiddenTextarea.value = targetElement.value || targetElement.placeholder || '';
  let height = hiddenTextarea.scrollHeight;   const result = {};
  if (boxSizing === 'border-box') {     height = height + borderSize;   } else if (boxSizing === 'content-box') {     height = height - paddingSize;   }
  hiddenTextarea.value = '';   let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize;
  if (minRows !== null) {     let minHeight = singleRowHeight * minRows;     if (boxSizing === 'border-box') {       minHeight = minHeight + paddingSize + borderSize;     }     height = Math.max(minHeight, height);     result.minHeight = `${ minHeight }px`;   }   if (maxRows !== null) {     let maxHeight = singleRowHeight * maxRows;     if (boxSizing === 'border-box') {       maxHeight = maxHeight + paddingSize + borderSize;     }     height = Math.min(maxHeight, height);   }   result.height = `${ height }px`;   hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);   hiddenTextarea = null;   return result; };