Tool-tip-ellipsis Global bubble prompt based on el-Tooltip secondary encapsulation


The output background

In the el-select drop-down component, there are usually multiple el-options that need to be iterated through, or made to scroll to load more el-Options. The content displayed by these el-Options can be very long, and if left unchecked, the dropdown will be too long, which may require default display (display beyond length…). The full content is displayed when the mouse moves over it.

The general approach is to use CSS for default display in El-Option, and then add an El-Tooltip for each el-Option that is iterated over. The advantage of this is that it is fast and simple, but the disadvantage is that each el-option generates a corresponding el-tooltip, equivalent to a one-to-one relationship. That is, if you iterate over 100 El-Options and then hover them all once, you will generate 100 el-Tooltips to insert into the document, as shown below.Above, there are six elements with el-tooltips, all hover once, and the console can see that six divs are generated

Optimization scheme

Global (VUEX) shares one instance of el-Tooltip, globalTemplateToolTip, which is a container.

Tool-tip-ellipsis is a component that triggers the display of globalTemplateToolTip. If you call this component, you will place the content you want to display in globalTemplateToolTip. This component replaces the usual el-Tooltip. The job of this component is to internally change the way el-ToolTip is triggered so that it does not generate additional DOM when it hovers.

Hover content in el-tooltip is displayed only when text overflows. Use CSS styles combined with JS to determine text overflow.

Without further ado, here we go

1. El-tooltip containers

First globally, such as in app. vue, according to their own project structure to make adjustments

APP.vue

<router-view v-if="isRouterAlive" />
<global-template-tool-tip></global-template-tool-tip>

import globalTemplateToolTip from '@/components/tool-tip'
Copy the code

Tool-tip.vue

<template> <el-tooltip ref="globalTemplateTip" :content="toolTipContent" :placement="toolTipPlacement"></el-tooltip> </template> mounted() {new code.store.mit (' MOUNT_TOOL_TIP', this.$refs.globalTemplatetip)} MOUNT_TOOL_TIP(state,) {new code.store.mit (' MOUNT_TOOL_TIP', this. node) { state.toolTip = node },Copy the code
2, Encapsulates the el-tooltip component (this is used directly in the component, the top is the container, used to store the content from hover)

tool-tip-ellipsis.vue

<template>
    <div @mouseenter="tipBoxEnter($event)" @mouseleave="tipBoxLeave($event)">
        <p :class="['too-tip-content-p', optionMaxWidth ? 'max-width-' + optionMaxWidth : '']">
            <slot></slot>
        </p>
    </div>
</template>
<script>
export default {
    props: {
	  // Maximum width, negligible
        optionMaxWidth: {
            type: Number
        },
	  / / content
        toolTipContent: {
            type: String.default: ' '
        },
	  / / position
        placement: {
            type: String.default: 'bottom'}},methods: {
        tipBoxEnter(e) {
            // Get the mounted p tag
            let p_Node = e.target.querySelector('.too-tip-content-p')
            // If the text overflows
            if (p_Node.scrollWidth > p_Node.offsetWidth) {
                // Initialize the global toolTip
                this.$store.commit('INIT_TOOL_TIP', {
                    node: p_Node,
                    content: this.toolTipContent,
                    placement: this.placement
                })
            }
        },
        tipBoxLeave(e) {
            / / destroy the toolTip
            this.$store.commit('CLOSE_TOOL_TIP')}}}</script>
<style lang="scss" scoped>
.too-tip-content-p {
    padding: 0;
    margin: 0;
    text-overflow: ellipsis;
    overflow: hidden;
}
</style>

Copy the code

The class name of max-width-xxx above is implemented using SCSS loops, placeholders, etc.

Note that writing this will generate a large number of class names, which will make the CSS file bigger and should be used with caution.

// Maximum width $max_width_i:1000;
$maxWidthList: ();

@while $max_width_i>0 {
    $maxWidthList: append($maxWidthList, $max_width_i, comma);
    $max_width_i: $max_width_i - 1;
}

@each $len in $maxWidthList {
    %max-width-#{$len} {
        max-width: #{$len}px;
    }

    .max-width-#{$len} {
        @extend%max-width-#{$len}; }}Copy the code

vuex

/ / initialization
INIT_TOOL_TIP(state, obj) {
	state.toolTip.referenceElm = obj.node
	// Get rid of the previous onesstate.toolTip.$refs.popper &amp; &amp; (state.toolTip.$refs.popper.style.display ='none')
	state.toolTip.doDestroy()
	// Set the condition variable in the component to true, otherwise handleClosePopper cannot be called
	state.toolTip.setExpectedState(true)
	// Display the new tool-tip
	activateTooltip(state.toolTip)
	// Fill in the content
	state.toolTipContent = content
	// Set the location
	state.toolTipPlacement = placement
},

/ / close
CLOSE_TOOL_TIP(state) {
	state.toolTip.setExpectedState(false)
	state.toolTip.handleClosePopper()
}
Copy the code

ToolTip source

use

<el-option
	v-for="(option, optIndex) in self_list"
	:key="optIndex + '-' + option.id"
	:label="Option [dictLabel] | | '-'"
	:value="option"
>
	<toolTipEllipsis
		:optionMaxWidth="200"
		:toolTipContent="option.content :placement="'top-start'"
	>
		{{ option.content }}
	</toolTipEllipsis>
</el-option>


import toolTipEllipsis from '@ / components/tool - tip - ellipsis/index'Copy the code

The effect

conclusion

It’s an interesting experiment. I hope it helps people in need. In order not to appear lengthy, save a lot of code, improper place, welcome to point out!

Reference links: blog.csdn.net/sgabon/arti…