我有工具提示自定义指令。如我所料,只有当我使用beforeUpdate钩子时,才能正常工作,而不是使用更新钩子。问题是,当我在h1上悬停使用mouseover和mouseleve时,会创建多个元素。
有一些方式,它将不会创建多个元素?
由于我是自定义指令的初学者,我将感谢您的任何帮助。
<div class="tooltip"><h1>Hello world from html</h1></div>
<div class="tooltip"><h1>Hello world from html</h1></div>
<div class="tooltip"><h1>Hello world from html</h1></div>
<div class="tooltip"><h1>Hello world from html</h1></div>tooltip.ts
const updateTooltip = (el: HTMLElement, value: DirectiveBinding["value"], modifiers: DirectiveBinding["modifiers"], arg: DirectiveBinding["arg"], vnode: VNode): void => {
if (!value.text) {
el.classList.remove("tooltip-parent")
}
if (value.text) {
tooltipDiv.classList.add("tooltip")
tooltipDiv.innerHTML = value.text
el.appendChild(tooltipDiv)
}
if (value.displayArrow) {
el.style.setProperty(Tooltip.arrowDisplay, "inline")
argTooltip?.style.setProperty(Tooltip.arrowDisplay, "inline")
}
tooltipPlacement(value, el, argTooltip, argTooltipDiv)
}
export const tooltip = {
mounted: (el: HTMLElement, { value, modifiers, arg }: DirectiveBinding): void => {
if (typeof value === "object" && value.text) {
el.classList.add("tooltip-parent")
}
if (typeof value === "string" && value) {
el.classList.add("tooltip-parent")
}
updateTooltip(el, value, modifiers, arg)
},
beforeUpdate: (el: HTMLElement, { value, modifiers, arg }: DirectiveBinding): void => {
updateTooltip(el, value, modifiers, arg)
},
}tooltipPlacement.ts
export const tooltipPlacement = (value: DirectiveBinding["value"], el: HTMLElement, argTooltip: HTMLElement, argTooltipDiv: HTMLDivElement) => {
if (value.theme) {
for (const [key, val] of Object.entries(value.theme) as [string, any][]) {
switch (key) {
case "hide":
watch(
() => val,
() => {
if (val) {
argTooltip?.style.setProperty(Tooltip.opacity, "0")
argTooltip?.style.setProperty(Tooltip.visibility, "hidden")
/**** arrow ****/
argTooltip?.style.setProperty(Tooltip.arrowOpacity, "0")
argTooltip?.style.setProperty(Tooltip.arrowVisibility, "hidden")
}
if (!val) {
console.log("show")
argTooltip?.style.setProperty(Tooltip.opacity, "1")
argTooltip?.style.setProperty(Tooltip.visibility, "visible")
/**** arrow ****/
argTooltip?.style.setProperty(Tooltip.arrowOpacity, "1")
argTooltip?.style.setProperty(Tooltip.arrowVisibility, "visible")
}
},
{ immediate: true },
)
break
default:
break
}
}
}
}模板
<template>
<div>
<div class="p-6 centered flex-col space-y-6">
{{ !!hideTooltip }}
<h1>Tooltip</h1>
<br />
<p v-tooltip:actions.arrow="tooltipContent(html, tooltipTheme, true)" class="border w-40 h-20 text-center">hello world</p>
</div>
<div class="p-6 centered flex-col space-y-6">
<h1 class="h-20" @mouseover="hideTooltip = false" @mouseleave="hideTooltip = true">Actions</h1>
<br />
<p class="h-60 border px-4 actions">Test of args tooltip</p>
<button class="mt-10 p-6" @click="hideTooltip = !hideTooltip">{{ hideTooltip ? "Show Tooltip" : "Hide" }}</button>
</div>
</div>
</template>脚本
<script lang="ts" setup>
import { tooltipContent, ThemeOptions } from "../directives/tooltip"
import { ref, computed } from "vue"
const hideTooltip = ref(true)
const html = ref("<h1>Hello world from html</h1>")
const tooltipTheme = computed((): ThemeOptions => {
return {
placement: "leftTop",
argTxt: html.value,
hide: !!hideTooltip.value,
maxWidth: "300px",
}
})
</script>发布于 2022-08-17 07:23:20
通过添加以下代码,它解决了这个问题
const hasTooltipClass = el.querySelector(".tooltip") as HTMLDivElement
if (!hasTooltipClass) {
tooltipDiv.classList.add("tooltip")
tooltipDiv.innerHTML = value
el.appendChild(tooltipDiv)
}https://stackoverflow.com/questions/73364387
复制相似问题