最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue中textarea自適應(yīng)高度方案的實(shí)現(xiàn)

 更新時(shí)間:2022年01月04日 11:49:52   作者:陳杰夫  
本文主要介紹了Vue中textarea自適應(yīng)高度方案的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

先給方案,Vue棧有需求的同學(xué)可以直接下載vue-awesome-textarea

隱藏的問(wèn)題

拋開(kāi)原生JS,框架的大部分UI庫(kù)都支持自適應(yīng)textarea高度功能,但普遍都忽略了一個(gè)功能,就是自適應(yīng)高度的回顯。

使用這些庫(kù)的時(shí)候,我們很容易的在textarea中鍵入內(nèi)容,超出范圍時(shí)會(huì)自動(dòng)延展一行,保證內(nèi)容高度的自適應(yīng)。當(dāng)我們提交內(nèi)容,在其它頁(yè)面使用同樣的UI來(lái)渲染時(shí),麻煩的就來(lái)了,有些UI庫(kù)是不支持自適應(yīng)回顯的,這就需要我們通過(guò)行高、行數(shù)甚至高度之間的計(jì)算得出一個(gè)基值,從而實(shí)現(xiàn)回顯。

解決自適應(yīng)高度的方案

常見(jiàn)得方案有兩種,一種是在頁(yè)面地“邊遠(yuǎn)地區(qū)”添加一個(gè)ghost dom來(lái)模擬輸入換行,這個(gè)dom的可能是editable屬性為true的div或者是一個(gè)一摸一樣得textarea。
以element-ui的input組件舉例,當(dāng)我們?cè)诮M件內(nèi)輸入值時(shí),會(huì)調(diào)用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);
}

當(dāng)設(shè)置了autosize為true則textarea設(shè)為自適應(yīng)高度。此時(shí)textarea的高度會(huì)通過(guò)calcTextareaHeight方法實(shí)時(shí)計(jì)算。

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創(chuàng)建了一個(gè)textarea的dom,通過(guò)calculateNodeStyling方法將真正的textarea的樣式復(fù)制給hiddenTextarea(overflow不同步,真正的textarea是為hidden)。接著監(jiān)聽(tīng)textarea的輸入值,同步給hiddenTextarea。同時(shí)將hiddenTextarea的scrollHeight同步給textarea的高度,最后再將dom銷毀掉。

關(guān)于樣式的同步,element這里用了getComputedStyle和getPropertyValue這兩個(gè)API。當(dāng)然,如果你自己封裝的話,也可以使用css預(yù)處理器的mixin。

第二種方案與第一種方案類似,不過(guò)不會(huì)創(chuàng)建額外的dom。以開(kāi)頭的vue-awesome-textarea舉例:

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

在頁(yè)面mounted或者內(nèi)容變動(dòng)且開(kāi)啟自適應(yīng)高度autoResize的時(shí)候,執(zhí)行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()是來(lái)初始化textarea的高度,默認(rèn)為auto。calcTextareaH()方法是用來(lái)計(jì)算內(nèi)容區(qū)域的高度(textarea的scrollHeight減去padding的高度),同時(shí)將計(jì)算好的高度實(shí)時(shí)同步給textarea的高:
this.height = this.calcHeightChange(contentHeight) + 'px'

相比方案一,這個(gè)方案采用的思路相同(動(dòng)態(tài)修改高度),但是減少了額外的dom創(chuàng)建和銷毀的過(guò)程。
此外,vue-awesome-textarea還支持在自適應(yīng)的過(guò)程中回調(diào)行數(shù),可以更好的支持?jǐn)?shù)據(jù)回顯。實(shí)現(xiàn)的方法也很簡(jiǎn)單:

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

在computed中我們計(jì)算出單行的高度,同時(shí)在執(zhí)行this.calcTextareaH()方法時(shí)我們記錄下內(nèi)容高度:

this.oldContentHeight = contentHeight

接著我們會(huì)比對(duì)是否存在添加行操作,一旦添加則新的內(nèi)容高度和老的內(nèi)容高度會(huì)不同:

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

此時(shí)我們會(huì)把最新的行高emit到組件外部:

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

到此這篇關(guān)于Vue中textarea自適應(yīng)高度方案的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Vue textarea自適應(yīng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue實(shí)現(xiàn)樹(shù)狀表格效果

    vue實(shí)現(xiàn)樹(shù)狀表格效果

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)樹(shù)狀表格效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Vue模擬響應(yīng)式原理底層代碼實(shí)現(xiàn)的示例

    Vue模擬響應(yīng)式原理底層代碼實(shí)現(xiàn)的示例

    最近去面試的人都會(huì)有這個(gè)體會(huì),去年面試官只問(wèn)我怎么用vue,今年開(kāi)始問(wèn)我vue響應(yīng)式原理,本文就詳細(xì)的介紹一下
    2021-08-08
  • vue中key使用的問(wèn)題示例解析

    vue中key使用的問(wèn)題示例解析

    這篇文章主要為大家介紹了vue中key使用的問(wèn)題示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Vue3+Element+Ts實(shí)現(xiàn)表單的基礎(chǔ)搜索重置等功能

    Vue3+Element+Ts實(shí)現(xiàn)表單的基礎(chǔ)搜索重置等功能

    本文主要介紹了Vue3+Element+Ts實(shí)現(xiàn)表單的基礎(chǔ)搜索重置等功能,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • vue2之簡(jiǎn)易的pc端短信驗(yàn)證碼的問(wèn)題及處理方法

    vue2之簡(jiǎn)易的pc端短信驗(yàn)證碼的問(wèn)題及處理方法

    這篇文章主要介紹了vue2之簡(jiǎn)易的pc端短信驗(yàn)證碼的問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-06-06
  • vue將單頁(yè)面改造成多頁(yè)面應(yīng)用的方法

    vue將單頁(yè)面改造成多頁(yè)面應(yīng)用的方法

    最近領(lǐng)導(dǎo)交我一個(gè)項(xiàng)目是使用 vue-cli 搭建的單頁(yè)面應(yīng)用。下面小編通過(guò)本文給大家介紹vue將單頁(yè)面改造成多頁(yè)面應(yīng)用的方法 ,感興趣的朋友一起看看吧
    2018-11-11
  • 詳解vue掛載到dom上會(huì)發(fā)生什么

    詳解vue掛載到dom上會(huì)發(fā)生什么

    這篇文章主要介紹了詳解vue掛載到dom上會(huì)發(fā)生什么,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • vue2中使用quill編輯器+表格功能(步驟詳解)

    vue2中使用quill編輯器+表格功能(步驟詳解)

    這篇文章主要介紹了vue2中使用quill編輯器+表格功能,本文分步驟結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 詳解Vue使用命令行搭建單頁(yè)面應(yīng)用

    詳解Vue使用命令行搭建單頁(yè)面應(yīng)用

    本篇文章主要介紹了詳解Vue使用命令行搭建單頁(yè)面應(yīng)用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • Vue.js實(shí)現(xiàn)圖片的隨意拖動(dòng)方法

    Vue.js實(shí)現(xiàn)圖片的隨意拖動(dòng)方法

    下面小編就為大家分享一篇Vue.js實(shí)現(xiàn)圖片的隨意拖動(dòng)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03

最新評(píng)論

湘潭县| 桃源县| 谷城县| 安达市| 巴彦县| 惠水县| 武夷山市| 扬中市| 专栏| 时尚| 冀州市| 罗山县| 灵璧县| 新丰县| 八宿县| 茂名市| 东兰县| 安庆市| 漳浦县| 临武县| 右玉县| 宜春市| 天祝| 濮阳县| 永清县| 江安县| 渝中区| 丰原市| 正阳县| 余姚市| 瑞昌市| 云浮市| 广德县| 枞阳县| 昌都县| 牙克石市| 长岭县| 古田县| 芦溪县| 庆云县| 海丰县|