vue自定义指令poptip的弹窗的代码

78 篇文章 2 订阅
40 篇文章 1 订阅
Vue自定义指令方法介绍
  1. 页面加载时:bind inserted 注意区别:bind与inserted:bind时父节点为null,inserted时父节点存在。
  2. 更新组件:update componentUpdated 注意区别:update与componentUpdated:update是数据更新前,componentUpdated是数据更新后。
  3. 卸载组件:unbind
  4. 重新安装组件:bind inserted
效果图

效果图

说明

使用到 onmouseenter(移入)和 onmouseleave(移出)方法。完成dom元素添加和删除。详细说明在代码注释里。复制粘贴就能用,因为框架不同会有一些差距,自行斟酌修改。

dom里使用方法
<span style="width:50px" v-be-poptip>{{item.name}}</span>
指令源码
Vue.directive('bePoptip', {
    inserted: bePoptip,
    componentUpdated: bePoptip,
    //指令与元素解绑时
    unbind: function (el, binding, vnode) {
        el.onmouseenter = undefined;
        el.onmouseleave = undefined;
        // 找到浮层元素并移除
        const vcTooltipDom = document.getElementById('be-tooltips');
        vcTooltipDom && document.body.removeChild(vcTooltipDom);
    }
})

function bePoptip(el, binding, vnode) {
    // 获取当前元素的Style
    const curStyle = window.getComputedStyle(el, '');
    // 创建一个容器来记录文字的width
    const textSpan = document.createElement('span');
    // 设置新容器的字体样式,确保与当前需要隐藏的样式相同
    textSpan.style.fontSize = curStyle.fontSize;
    textSpan.style.fontWeight = curStyle.fontWeight;
    textSpan.style.fontFamily = curStyle.fontFamily;
    // 将容器插入body,如果不插入,offsetWidth为0
    document.body.appendChild(textSpan);
    // 设置新容器的文字
    textSpan.innerHTML = el.innerText;
    // 如果字体元素大于当前元素,则需要隐藏(*...)
    if (textSpan.offsetWidth > el.offsetWidth) {
        // 给当前元素设置超出隐藏
        el.style.overflow = 'hidden';
        el.style.textOverflow = 'ellipsis';
        el.style.whiteSpace = 'nowrap';
        // 鼠标移入
        el.onmouseenter = function (e) {
            // 创建浮层元素并设置样式
            const vcTooltipDom = document.createElement('div');
            vcTooltipDom.style.cssText = `
                  max-width:34rem;
                  max-height: 34rem;
                  overflow: auto;
                  position:absolute;
                  top:${e.clientY + 5}px;
                  left:${e.clientX - 50}px;
                  background: rgba(70, 76, 91, 0.9);
                  color:#fff;
                  border-radius:0.417rem;
                  padding:0.833rem;
                  display:inline-block;
                  font-size:1.167rem;
                  z-index:19999
                `
            // 设置id方便寻找
            vcTooltipDom.setAttribute('id', 'be-tooltips');
            // 将浮层插入到body中
            document.body.appendChild(vcTooltipDom);
            // 浮层中的文字
            document.getElementById('be-tooltips').innerHTML = el.innerText;
        }
        // 鼠标移出
        el.onmouseleave = function () {
            // 找到浮层元素并移出
            const vcTooltipDom = document.getElementById('be-tooltips');
            vcTooltipDom && document.body.removeChild(vcTooltipDom);
        }
    }
    // 记得移除刚刚创建的记录文字的容器
    document.body.removeChild(textSpan)
}

如果样式有特殊的要求,可以在body里添加样式,不能使用scoped。代码如下
<style lang="less"> 
html,
body {
	#be-tooltips {
		max-width:34rem;
        max-height: 34rem;
        overflow: auto;
        position:absolute;
        background: rgba(70, 76, 91, 0.9);
        color:#fff;
        border-radius:0.417rem;
        padding:0.833rem;
        display:inline-block;
        font-size:1.167rem;
        z-index:19999
}
</style>
进阶版Poptip

效果图

在这里插入图片描述

dom里使用方法
<div v-for="(item ,i) in data" :key="'div'+i" v-be-poptip-policy="item"><div>
指令源码
Vue.directive('bePoptipPolicy', {
    inserted: function (el, binding, vnode) {
        // 鼠标移入
        el.onmouseenter = (e) => {
            // 接受数据,根据业务不同,你们可以调整咯。
            let item = binding.value;
            let strItemY = ``;
            let strItemN = ``;
            for (let index = 0; index < item.list.length; index++) {
                const info = item.list[index];
                if (info.type=== 'Y') {
                    strItemY += `<span style="padding-left: 0.417rem;" :key="${index + '_Y'}" >${info.name}</span>`
                }
                if (info.type=== 'N') {
                    strItemN += `<div class="content-btn" :key="${index + '_N'}">${info.name}</div>`
                }
            }
            let str1 =
                `<div class="move_content_title">
                    <div class="move_content_title_inner">${item.name}</div>
                    <span class="move_content_title-btn">${ item.name1}</span>
                </div>`;
            let str2 =
                `<div class="move_content_poptip">
                    <div class="item">
                        <div class="name">谁是大哥:</div>
                        <div class="content">
                        ` + strItemY + `
                        </div>
                    </div>
                    <div class="item">
                        <div class="name">谁是小弟:</div>
                        <div class="content">
                        ` + strItemN + `
                        </div>
                    </div>
                </div>`;
            // 创建浮层元素并设置样式  top:${e.clientY}px; left:${e.clientX}px;
            const vcTooltipDom = document.createElement('div');
            // 设置id方便寻找
            vcTooltipDom.setAttribute('id', 'node_poptip');
            vcTooltipDom.style.cssText = `top:${getTop(el) / 12 + 1.5}rem; left:${getLeft(el) / 12 + 7.5}rem;`
            // 将浮层插入到body中
            document.body.appendChild(vcTooltipDom);
            // 浮层中的文字
            document.getElementById('node_poptip').innerHTML = str1 + str2;
        }
        // 鼠标移出
        el.onmouseleave = () => {
            // 找到浮层元素并移出
            const vcTooltipDom = document.getElementById('node_poptip');
            vcTooltipDom && document.body.removeChild(vcTooltipDom);
        }
    },
    // 指令与元素解绑时
    unbind: function (el, binding, vnode) {
        el.onmouseenter = undefined;
        el.onmouseleave = undefined;
        // 找到浮层元素并移除
        const vcTooltipDom = document.getElementById('node_poptip');
        vcTooltipDom && document.body.removeChild(vcTooltipDom);
    }
})
//获取元素的纵坐标(相对于窗口)
function getTop(e) {
    var offset = e.offsetTop - e.scrollTop;
    if (e.offsetParent != null) offset += getTop(e.offsetParent);
    return offset;
};
//获取元素的横坐标(相对于窗口)
function getLeft(e) {
    var offset = e.offsetLeft - e.scrollLeft;
    if (e.offsetParent != null) offset += getLeft(e.offsetParent);
    return offset;
};
css样式。绑定在body。
<style lang="less"> 
html,
body {
	#node_poptip {
		max-width: 34rem;
		max-height: 34rem;
		overflow: auto;
		position: absolute;
		background: #242f39;
		color: #fff;
		border-radius: 0.417rem;
		padding: 0.833rem;
		display: inline-block;
		font-size: 1.167rem;
		z-index: 19999;
        
		.move_content_title {
			position: relative;
			display: flex;
			flex-direction: row;
			margin: 0;
			border-bottom: 0.083rem solid  #ffffff;
			margin-bottom: 0.5rem;
			padding-bottom: 0.5rem;
			.move_content_title_inner {
				display: flex;
				color: #ffffff;
				font-size: 12px;
				font-weight: 500;
				padding: 2px 2px;
			}

			.move_content_title-btn {
				color: #ffffff;
				font-size: 12px;
				border-radius: 5px;
				border: 1px solid #ffffff;
				background-color: rgba(25, 255, 216, 0.1);
				margin-left: 10px;
				padding: 0px 5px;
				height: 20px;
			}
		}
		.move_content_poptip {
			.item {
				display: flex;
				flex-direction: row;
				justify-content: space-between;
				font-size: 12px;
				height: 24px;

				.name {
					display: flex;
					align-items: center;
					color: #ffffff;
				}

				.content {
					display: flex;
					align-items: center;
					color: #f0f5ff;

					.content-btn {
						color: rgba(240, 245, 255, 0.6);
						font-size: 12px;
						line-height: 12px;
						border-radius: 4px;
						border: 1px solid #f0f5ff;
						background-color: rgba(240, 245, 255, 0.1);
						align-items: center !important;
						text-align: center !important;
						margin-left: 5px !important;
						padding: 2px 2px !important;
					}
				}
			}
		}
	}
}
</style>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue自定义指令失效的原因可能有很多种情况。根据引用和引用的内容,可以推测一些可能的原因和解决方法。 1. 指令未正确注册:在Vue中,自定义指令需要先进行注册,然后才能在模板中使用。请确保自定义指令已经正确地注册到Vue实例中。你可以使用全局注册或局部注册的方式进行注册。全局注册可以通过Vue.directive方法全局注册所有的指令,如引用所示。局部注册可以在组件内部使用directives选项进行指令的注册。 2. 指令名称不正确:请确保你在模板中正确地使用了自定义指令的名称。指令名称应该是以v-开头的,比如v-imgerror。 3. 指令绑定值错误:自定义指令可以通过绑定值来传递参数。请确保你正确地传入了绑定值,并且在指令定义中正确地使用了这些值。 4. 指令逻辑错误:自定义指令的逻辑代码可能有问题,导致指令无法正常工作。请检查指令的代码逻辑,确保代码没有错误。 5. 图片加载问题:自定义指令在处理图片加载问题时可能会出现失效的情况。请检查你的指令逻辑,确认图片加载错误时是否正确地触发了相关的处理逻辑。 总结来说,如果Vue自定义指令失效,首先要检查指令是否正确注册、名称是否正确、绑定值是否正确、代码逻辑是否正确,以及是否正确处理了图片加载问题。通过排查这些可能的原因,你应该能够找到并解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值