From 649c38d650fe32a9f5433f9b0349fe6a588dde12 Mon Sep 17 00:00:00 2001 From: Guillaume Chau Date: Tue, 18 Jan 2022 17:33:58 +0100 Subject: [PATCH] feat: single app for v-tooltip directives --- .../src/views/directive/VTooltipDemo1.vue | 2 +- .../floating-vue/src/directives/v-tooltip.ts | 71 ++++++++++++------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/packages/demo-vue3/src/views/directive/VTooltipDemo1.vue b/packages/demo-vue3/src/views/directive/VTooltipDemo1.vue index a0621e72..5ca8a6b7 100644 --- a/packages/demo-vue3/src/views/directive/VTooltipDemo1.vue +++ b/packages/demo-vue3/src/views/directive/VTooltipDemo1.vue @@ -10,6 +10,6 @@ Et consectetur voluptates magnam quia dolor fugiat quod aliquid. Nihil sunt quasi provident qui ea et beatae est. Dolorem dicta optio deserunt. - Saepe neque quaerat sint architecto labore quos consequatur. Sequi perspiciatis dolores sunt occaecati quas ratione aut aliquam. Repellat iusto et et cum fuga. + Saepe neque quaerat sint architecto labore quos consequatur. Sequi perspiciatis dolores sunt occaecati quas ratione aut aliquam. Repellat iusto et et cum fuga. diff --git a/packages/floating-vue/src/directives/v-tooltip.ts b/packages/floating-vue/src/directives/v-tooltip.ts index b646890f..667257a3 100644 --- a/packages/floating-vue/src/directives/v-tooltip.ts +++ b/packages/floating-vue/src/directives/v-tooltip.ts @@ -1,4 +1,4 @@ -import { createApp, h, ref } from 'vue' +import { App, createApp, h, Ref, ref } from 'vue' import TooltipDirective from '../components/TooltipDirective.vue' import { getDefaultConfig } from '../config' import { placements } from '../util/popper' @@ -39,32 +39,54 @@ export function getOptions (el, value, modifiers) { return options } -export function createTooltip (el, value, modifiers) { - const options = ref(getOptions(el, value, modifiers)) - const component = ref() +interface Directive { + options: Ref + shown: Ref +} + +let directiveApp: App +let directives: Ref - const tooltipApp = createApp({ - name: 'VTooltipDirective', +function ensureDirectiveApp () { + if (directiveApp) return + + directives = ref([]) + + directiveApp = createApp({ + name: 'VTooltipDirectiveApp', setup () { return { - options, - tooltip: component, + directives, } }, render () { - return h(TooltipDirective, { - ...this.options, - ref: 'tooltip', + return this.directives.map((directive) => { + return h(TooltipDirective, { + ...directive.options, + shown: directive.shown.value || directive.options.shown, + }) }) }, devtools: { hide: true, }, }) + const mountTarget = document.createElement('div') document.body.appendChild(mountTarget) - tooltipApp.mount(mountTarget) - el.$_popperMountTarget = mountTarget + directiveApp.mount(mountTarget) +} + +export function createTooltip (el, value, modifiers) { + ensureDirectiveApp() + const options = ref(getOptions(el, value, modifiers)) + const shown = ref(false) + + const item = { + options, + shown, + } + directives.value.push(item) // Class on target if (el.classList) { @@ -72,14 +94,13 @@ export function createTooltip (el, value, modifiers) { } const result = el.$_popper = { - app: tooltipApp, options, - component, + item, show () { - component.value.show() + shown.value = true }, hide () { - component.value.hide() + shown.value = false }, } @@ -88,10 +109,8 @@ export function createTooltip (el, value, modifiers) { export function destroyTooltip (el) { if (el.$_popper) { - el.$_popper.app.unmount() - if (el.$_popperMountTarget.parentElement) { - el.$_popperMountTarget.parentElement.removeChild(el.$_popperMountTarget) - } + const index = directives.value.indexOf(el.$_popper.item) + if (index !== -1) directives.value.splice(index, 1) delete el.$_popper delete el.$_popperOldShown @@ -108,18 +127,18 @@ export function bind (el, { value, oldValue, modifiers }) { if (!options.content || getDefaultConfig(options.theme || 'tooltip', 'disabled')) { destroyTooltip(el) } else { - let tooltipApp + let directive if (el.$_popper) { - tooltipApp = el.$_popper - tooltipApp.options.value = options + directive = el.$_popper + directive.options.value = options } else { - tooltipApp = createTooltip(el, value, modifiers) + directive = createTooltip(el, value, modifiers) } // Manual show if (typeof value.shown !== 'undefined' && value.shown !== el.$_popperOldShown) { el.$_popperOldShown = value.shown - value.shown ? tooltipApp.show() : tooltipApp.hide() + value.shown ? directive.show() : directive.hide() } } }