[英]Vue 3 custom directive
I have tooltip custom directive.我有工具提示自定义指令。 Is working as I expected, only when I use beforeUpdate hooks, not working on update hooks.
仅在我使用 beforeUpdate 挂钩时按预期工作,而不是在更新挂钩上工作。 The problem is that is creating multiple element when I hovering on h1 where I'm using mouseover and mouseleve.
问题是,当我将鼠标悬停在使用 mouseover 和 mouseleve 的 h1 上时,会创建多个元素。
There is some way that it will not create multiple elements?有什么方法不会创建多个元素?
As I'm beginner on custom directive I'll appreciate any of your help.由于我是自定义指令的初学者,我将不胜感激您的任何帮助。
<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工具提示.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 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模板
<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脚本
<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>
By adding the following code, it fixed the issue通过添加以下代码,它解决了问题
const hasTooltipClass = el.querySelector(".tooltip") as HTMLDivElement
if (!hasTooltipClass) {
tooltipDiv.classList.add("tooltip")
tooltipDiv.innerHTML = value
el.appendChild(tooltipDiv)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.