vue-ellipsis-component 的誕生
文字縮略是業務中最常見的需求之一,通常我們使用 webkit-line-clamp
實現文字縮略,但這僅限於多行縮略,若是萬惡的 PM 腦子一熱需要你支援超過某個高度時進行縮略...... 為了讓自己不會在這種場景下束手無措,我決定先摸索一下現有的 vue 縮略元件!
在一番尋找下,我發現一個 vue 縮略元件: 顧軼靈開源的 vue-clamp,大致功能如下:
- 支援多行縮略
- 支援超過最大高度時縮略
- 支援自定義縮略符,同時支援自定義縮略符出現的位置
- 支援縮略回撥,在發生截斷時觸發
- 支援自適應縮略
vue-clamp 支援的功能挺全的,行數截斷的實現原理也是相當有趣,主要是利用 getClientRects
API 的特性,可以直接獲取到行內元素的行數,因此不需要手動設定 line-height
,具體可以檢視 MDN!
然而 vue-clamp 只支援純文字縮略,若是遇到富文字場景則捉襟見肘,就在這時,我發現一個 react 的縮略元件: react-ellipsis,功能更全:
- 支援多行縮略
- 支援超過最大高度時縮略
- 支援自定義縮略符
- 支援縮略回撥,在發生截斷時觸發
- 支援富文字縮略
- 支援尾文字過濾
- 支援自適應縮略
- 超過 n 行時展示 m 行
- 超過高度 n 時展示 高度 n
確認過眼神,是我需要的人 (✺ω✺) 可惜它是個 react 元件,於是乎,動起手來,把它移植 (抄) 成 vue 元件~ vue-ellipsis-component 就這麼誕生了!
簡單介紹一下元件的功能以及原理
舉一個 ?
vue-ellipsis-component 完整移植了 react-ellipsis 的功能 (抄也要抄得完整),舉個簡單的 demo:
<template>
<vue-ellipsis
:visible-line="2"
text="這是一段非常非常非常非常非常非常非常非常非常非常非常長的話">
</vue-ellipsis>
</template>
更多的 demo 可以檢視 文件 ~
縮略策略
vue-ellipsis-component 會根據傳入 props 的複雜度採用不同的縮略策略,比如上面的例子,只傳入了 text
和 visibleLine
進行多行縮略,因此元件會基於常規策略實現多行縮略: 利用 css -webkit-line-clamp
屬性進行縮略; 若是需要在超過最大高度時進行縮略,則會採用動態計算策略: 利用 JavaScript 動態計算得出縮略點,再進行文字內容的裁剪,比如以下的 demo:
<template>
<vue-ellipsis
:visible-height="60"
text="這是一段非常非常非常非常非常非常非常非常非常非常非常長的話">
</vue-ellipsis>
</template>
並且在動態計算策略中,vue-ellipsis-component 使用二分法提升了文字縮略的效能!
自適應縮略
vue-ellipsis-component 通過傳入 reflowOnResize
開啟自適應縮略,預設使用 ResizeObserver
監聽容器的變化,若是瀏覽器不支援 ResizeObserver
,則使用 window.resize
作為降級方案 ?
<template>
<vue-ellipsis
:visible-line="2"
text="這是一段非常非常非常非常非常非常非常長的話"
reflowOnResize>
</vue-ellipsis>
</template>
富文字縮略
vue-ellipsis-component 通過傳入 useInnerHtml
開啟富文字縮略,將 text
作為 HTML 插入到 dom 中,因此需要自行確保 text
內容,防止 XSS 攻擊!
<template>
<vue-ellipsis
:visible-line="2"
use-inner-html
text="<b>這是一段</b><u>非常非常非常非常非常非常非常非常非常非常非常長</u>的話">
</vue-ellipsis>
</template>
元件的不足
與 vue-clamp 不同的是,vue-ellipsis-component 需要你手動設定一個line-height
:
在滿足常規策略的情況下,是否主動設定 line-height
其實對縮略結果並沒有影響,而在動態計算縮略下 line-height
則有可能會導致縮略結果不如預期;
動態計算的縮略策略,是根據 line-height
與傳入的 visibleLine
進行計算得出一個可見高度,再利用可見高度和當前容器的高度做比較,從而判斷是否需要進行文字裁剪。可以看出,這一過程很大程度地依賴 line-height
;當 line-height
為預設值 normal
時,實際的行高取決於瀏覽器,但各個瀏覽器的取值可能不太一致。vue-ellipsis-component 會相容 line-height: normal
的情況,但為了保證在不同瀏覽器的縮略效果一致,最好還是主動設定一個 line-height
!
倉庫地址
Github 地址: vue-ellipsis-component
文件地址: docs
如果覺得對你有所幫助,可以在你的專案中安裝進行使用,或是給個 star ⭐️!
問題反饋
如果發現元件中存在的問題或是不足,可以提交你的問題到 github issue,或提交一個 Pull Request,感謝你的參與!