中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue中textarea自適應高度方案怎么實現

發布時間:2022-01-04 14:43:44 來源:億速云 閱讀:231 作者:iii 欄目:開發技術

本篇內容介紹了“Vue中textarea自適應高度方案怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

隱藏的問題

拋開原生JS,框架的大部分UI庫都支持自適應textarea高度功能,但普遍都忽略了一個功能,就是自適應高度的回顯。

使用這些庫的時候,我們很容易的在textarea中鍵入內容,超出范圍時會自動延展一行,保證內容高度的自適應。當我們提交內容,在其它頁面使用同樣的UI來渲染時,麻煩的就來了,有些UI庫是不支持自適應回顯的,這就需要我們通過行高、行數甚至高度之間的計算得出一個基值,從而實現回顯。

解決自適應高度的方案

常見得方案有兩種,一種是在頁面地“邊遠地區”添加一個ghost dom來模擬輸入換行,這個dom的可能是editable屬性為true的div或者是一個一摸一樣得textarea。
以element-ui的input組件舉例,當我們在組件內輸入值時,會調用resizeTextarea方法

resizeTextarea() {
  if (this.$isServer) return;
  const { autosize, type } = this;
  if (type !== 'textarea') return;
  if (!autosize) {
    this.textareaCalcStyle = {
      minHeight: calcTextareaHeight(this.$refs.textarea).minHeight
    };
    return;
  }
  const minRows = autosize.minRows;
  const maxRows = autosize.maxRows;

  this.textareaCalcStyle = calcTextareaHeight(this.$refs.textarea, minRows, maxRows);
}

當設置了autosize為true則textarea設為自適應高度。此時textarea的高度會通過calcTextareaHeight方法實時計算。

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;
};

我們可以看到

if (!hiddenTextarea) {
  hiddenTextarea = document.createElement('textarea');
  document.body.appendChild(hiddenTextarea);
}

element-ui創建了一個textarea的dom,通過calculateNodeStyling方法將真正的textarea的樣式復制給hiddenTextarea(overflow不同步,真正的textarea是為hidden)。接著監聽textarea的輸入值,同步給hiddenTextarea。同時將hiddenTextarea的scrollHeight同步給textarea的高度,最后再將dom銷毀掉。

關于樣式的同步,element這里用了getComputedStyle和getPropertyValue這兩個API。當然,如果你自己封裝的話,也可以使用css預處理器的mixin。

第二種方案與第一種方案類似,不過不會創建額外的dom。以開頭的vue-awesome-textarea舉例:

init() {
  this.initAutoResize()
},
initAutoResize () {
  this.autoResize && this.$nextTick(this.calcResize)
}

在頁面mounted或者內容變動且開啟自適應高度autoResize的時候,執行this.calcResize方法。

calcResize() {
  this.resetHeight()
  this.calcTextareaH()
},

resetHeight() {
  this.height = 'auto'
},

calcTextareaH() {
  let contentHeight = this.calcContentHeight()
  this.height = this.calcHeightChange(contentHeight) + 'px'
  if (this.needUpdateRows(contentHeight)) {
    this.updateRows(contentHeight)
  }
  this.oldContentHeight = contentHeight
},

calcContentHeight () {
  const { paddingSize } = this.calcNodeStyle(this.$el)
  return this.$el.scrollHeight - paddingSize
},

resetHeight()是來初始化textarea的高度,默認為auto。calcTextareaH()方法是用來計算內容區域的高度(textarea的scrollHeight減去padding的高度),同時將計算好的高度實時同步給textarea的高:
this.height = this.calcHeightChange(contentHeight) + 'px'

相比方案一,這個方案采用的思路相同(動態修改高度),但是減少了額外的dom創建和銷毀的過程。
此外,vue-awesome-textarea還支持在自適應的過程中回調行數,可以更好的支持數據回顯。實現的方法也很簡單:

computed: {
  ...
  oneRowsHeight() {
    return this.calcContentHeight() / Number(this.rows) || 0
  }
  ...
}

在computed中我們計算出單行的高度,同時在執行this.calcTextareaH()方法時我們記錄下內容高度:

this.oldContentHeight = contentHeight

接著我們會比對是否存在添加行操作,一旦添加則新的內容高度和老的內容高度會不同:

needUpdateRows(newContentHeight) {
  return this.oldContentHeight !== newContentHeight
},

此時我們會把最新的行高emit到組件外部:

updateRows(contentHeight) {
  this.$emit('getRows', Math.round(contentHeight / this.oneRowsHeight))
}

“Vue中textarea自適應高度方案怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

忻州市| 虎林市| 平昌县| 安远县| 应用必备| 聂拉木县| 泸定县| 钟山县| 泰安市| 容城县| 乐山市| 舞钢市| 敦煌市| 湖口县| 隆德县| 大埔县| 贺兰县| 宝丰县| 贵州省| 庄河市| 泰宁县| 华亭县| 邮箱| 承德市| 贵阳市| 黔南| 康保县| 大安市| 金昌市| 麻阳| 南投县| 景宁| 玉林市| 陆丰市| 屏南县| 宁化县| 基隆市| 清镇市| 铁力市| 拉萨市| 鄂尔多斯市|