vue-ellipsis-component: 滿足多種場景的 vue 縮略元件

Ruofee發表於2022-02-12

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 的複雜度採用不同的縮略策略,比如上面的例子,只傳入了 textvisibleLine 進行多行縮略,因此元件會基於常規策略實現多行縮略: 利用 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,感謝你的參與!

相關文章