Vue實(shí)現(xiàn)判斷文本是否超出郊尝,超出后顯示省略號(hào)并且hover展示全部?jī)?nèi)容

平常做項(xiàng)目總會(huì)遇到文字太長(zhǎng)二跋,有的顯示1行,超出隱藏虚循,有的顯示兩行同欠,而且還會(huì)遇到鼠標(biāo)hover時(shí)展示省略的部分,考慮用vue封裝成公用的組件横缔。

需要用到以下內(nèi)容

  1. 文字超出多行隱藏
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2; //行數(shù)
-webkit-box-orient: vertical;
  1. 判斷文字是否處于隱藏的狀態(tài)

需要涉及到獲取文字在標(biāo)簽寬度下的實(shí)際高度铺遂,動(dòng)態(tài)加上css控制溢出隱藏。使用getComputedStyle方法計(jì)算元素的高度height和行高茎刚,行高乘以行數(shù)得到隱藏后的高度height1襟锐,當(dāng)height超過(guò)height1時(shí),當(dāng)前應(yīng)處于被隱藏狀態(tài)

let lineHeight = getComputedStyle(element).lineHeight.replace("px", "") - 0 || 20;
let height = getComputedStyle(element).height.replace("px", "") - 0;
//這里使用-0將字符串轉(zhuǎn)化成數(shù)字

組件結(jié)構(gòu)

1.png

組件全量代碼如下

<template>
  <div
    class="vue-text"
    ref="text"
    :style="textStyle"
    @mouseenter="mouseenter"
    @mouseleave="mouseleave"
  >
    {{ value }}
  </div>
</template>

<script>
export default {
  // 顯示文字組件膛锭,可以設(shè)置最多顯示幾行粮坞,超過(guò)后會(huì)隱藏并且鼠標(biāo)hover顯示全部信息(需要給組件設(shè)置寬度)
  name: "VueText",
  props: {
    value: {
      type: String,
      default: "",
    },
    row: {
      //最多顯示幾行,超過(guò)后會(huì)...隱藏 為0時(shí)不隱藏
      type: [Number, String],
      default: 0,
    },
  },
  computed: {
    text() {
      return this.$refs.text;
    },
  },
  data() {
    return {
      isShowHover: false,
      textStyle: {},
      div: null,
    };
  },
  watch: {
    row: function (val) {
      this.init();
    },
    value: function () {
      this.isShowHover = false;
      this.textStyle = {
        cursor: "text",
      };
      this.$nextTick(() => {
        this.getStyle(this.row - 0);
      });
    },
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      this.div = document.querySelector(".hover-wrap");
      if (!this.div && this.row - 0) {
        this.div = document.createElement("div");
        this.div.className = "hover-wrap";
        this.div.style.top = 0;
        this.div.style.left = 0;
        document.body.append(this.div);
      }
      if (this.div && this.row - 0) {
        this.getStyle(this.row - 0);
      }
    },
    getStyle(val) {
      let lineHeight = getComputedStyle(this.text).lineHeight.replace("px", "") - 0 || 20;
      let height = getComputedStyle(this.text).height.replace("px", "") - 0;
      if (height > lineHeight * val) {
        this.isShowHover = true;
        this.textStyle = {
          height: `${lineHeight * val}px`,
          overflow: "hidden",
          textOverflow: "ellipsis",
          display: "-webkit-box",
          webkitLineClamp: val,
          webkitBoxOrient: "vertical",
          cursor: "pointer",
        };
      } else {
        this.isShowHover = false;
        this.textStyle = {
          cursor: "text",
        };
      }
    },
    mouseenter(e) {
      if (!this.isShowHover) {
        return;
      }
      let box = e.target.getBoundingClientRect();
      let top = box.top + box.height + "px";
      let left = 0;
      this.div.innerHTML = this.value;
      left =
        box.left +
        (box.width - this.div.getBoundingClientRect().width) / 2 +
        "px";
      this.div.style.top = top;
      this.div.style.left = left;
      this.div.classList.add("active");
    },
    mouseleave(e) {
      if (!this.isShowHover) {
        return;
      }
      if (e.relatedTarget !== this.div) {
        this.div.style.top = 0;
        this.div.style.left = 0;
        this.div.classList.remove("active");
      }
      this.div.onmouseleave = () => {
        this.div.style.top = 0;
        this.div.style.left = 0;
        this.div.classList.remove("active");
      };
    },
  },
};
</script>

<style lang="css">
.hover-wrap {
  position: absolute;
  background-color: #fff;
  color: #666;
  font-size: 14px;
  line-height: 1.4;
  padding: 6px 10px;
  border-radius: 5px;
  border: 1px solid #eee;
  max-width: 400px;
  transition: opacity 0.3s linear;
  z-index: -1;
  opacity: 0;
}
.hover-wrap.active {
  z-index: 1999;
  opacity: 1;
}
</style>

組件接受兩個(gè)參數(shù)初狰,value:展示的文字內(nèi)容莫杈,row:最多展示幾行(需要給組件設(shè)置寬度),同時(shí)在body插入了一個(gè)div奢入,hover展示文字的全部?jī)?nèi)容筝闹。

index.js文件代碼如下

import VueText from './VueText'
const component = {
    install: function(Vue){
        Vue.component('VueText',VueText)
    }
}
export default component

在組件內(nèi)的使用

  1. 在main.js內(nèi)引用
import component from '@/components/VueText'
Vue.use(component)
  1. 在組件內(nèi)的引用
import VueText from '@/components/VueText'
export default {
  name: "xxx",
  components: {
    VueText 
  }
}
  1. 使用
<vue-text
value="遙襟甫暢,逸興遄飛腥光。爽籟發(fā)而清風(fēng)生关顷,纖歌凝而白云遏。睢園綠竹武福,氣凌彭澤之樽议双;鄴水朱華,光照臨川之筆捉片。四美具平痰,二難并汞舱。窮睇眄于中天,極娛游于暇日宗雇。天高地迥兵拢,覺(jué)宇宙之無(wú)窮;興盡悲來(lái)逾礁,識(shí)盈虛之有數(shù)说铃。望長(zhǎng)安于日下,目吳會(huì)于云間嘹履。地勢(shì)極而南溟深腻扇,天柱高而北辰遠(yuǎn)。關(guān)山難越砾嫉,誰(shuí)悲失路之人幼苛?萍水相逢,盡是他鄉(xiāng)之客焕刮。"
style="width: 300px"
row="2"
/>

ps: 有小伙伴提了個(gè)bug舶沿,當(dāng)頁(yè)面滾動(dòng)時(shí),彈窗的位置會(huì)出現(xiàn)問(wèn)題配并,然后重新寫了下括荡,獲取組件最近一個(gè) overflow 值為 auto 或 scroll 的父元素,監(jiān)聽(tīng)滾動(dòng)溉旋,滾動(dòng)時(shí)關(guān)閉彈窗畸冲。同時(shí)加上了高度碰撞檢測(cè)。代碼地址:vue-cy-admin

再次更新观腊,最近在寫vue3邑闲,又寫了一版vue3的版本,新建一個(gè)vue文件梧油,彈窗提示直接用的element-plus的tooltip

<script lang="jsx">
export default defineComponent({
    props: {
        value: {
            type: String,
            default: ''
        },
        row: {
            type: [Number, String],
            default: 0
        },
        width: {
            type: String,
            default: '100%'
        }
    },
    setup: (props) => {
        let { value, row, width } = props
        let isShowHover = ref(false)
        let textStyle = ref({
            width
        })
        // 獲取ref
        const text = ref('')
        const textShow = (el) => {
            text.value = el
        }
        // 計(jì)算樣式
        const getStyle = (val) => {
            let lineHeight = getComputedStyle(text.value).lineHeight.replace('px', '') - 0
            let height = getComputedStyle(text.value).height.replace('px', '') - 0
            if (height > lineHeight * val) {
                isShowHover.value = true
                textStyle.value = {
                    height: `${lineHeight * val}px`,
                    overflow: 'hidden',
                    textOverflow: 'ellipsis',
                    display: '-webkit-box',
                    webkitLineClamp: val,
                    webkitBoxOrient: 'vertical',
                    cursor: 'pointer',
                    width
                }
            } else {
                isShowHover.value = false
                textStyle.value = {
                    cursor: 'text',
                    width
                }
            }
        }
        onMounted(() => {
            getStyle(row)
        })
        return () => (
            isShowHover.value
                ? <el-tooltip content={value} placement="top" effect="light" visible-arrow={false}>
                    <div ref={textShow} style={textStyle.value}>{value}</div>
                </el-tooltip>
                : <div ref={textShow} style={textStyle.value}>{value}</div>
        )
    }
})
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末苫耸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子儡陨,更是在濱河造成了極大的恐慌褪子,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迄委,死亡現(xiàn)場(chǎng)離奇詭異褐筛,居然都是意外死亡类少,警方通過(guò)查閱死者的電腦和手機(jī)叙身,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)硫狞,“玉大人信轿,你說(shuō)我怎么就攤上這事晃痴。” “怎么了财忽?”我有些...
    開(kāi)封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵倘核,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我即彪,道長(zhǎng)紧唱,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任隶校,我火速辦了婚禮漏益,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘深胳。我一直安慰自己绰疤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布舞终。 她就那樣靜靜地躺著轻庆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪敛劝。 梳的紋絲不亂的頭發(fā)上余爆,一...
    開(kāi)封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音夸盟,去河邊找鬼龙屉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛满俗,可吹牛的內(nèi)容都是我干的转捕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼唆垃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼五芝!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起辕万,我...
    開(kāi)封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤枢步,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后渐尿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體醉途,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年砖茸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了隘擎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凉夯,死狀恐怖货葬,靈堂內(nèi)的尸體忽然破棺而出采幌,到底是詐尸還是另有隱情,我是刑警寧澤震桶,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布休傍,位于F島的核電站,受9級(jí)特大地震影響蹲姐,放射性物質(zhì)發(fā)生泄漏磨取。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一柴墩、第九天 我趴在偏房一處隱蔽的房頂上張望寝衫。 院中可真熱鬧,春花似錦拐邪、人聲如沸慰毅。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汹胃。三九已至,卻和暖如春东臀,著一層夾襖步出監(jiān)牢的瞬間着饥,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工惰赋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宰掉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓赁濒,卻偏偏與公主長(zhǎng)得像轨奄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拒炎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容