|
<script setup> |
|
import { ref } from 'vue' |
|
|
|
const show = ref(true); |
|
function toggleShow() { |
|
show.value = !show.value; |
|
} |
|
|
|
// see https://github.com/vuejs/core/blob/v3.2.33/packages/runtime-dom/src/directives/vShow.ts |
|
const vVisible = { |
|
beforeMount(el, { value }, { transition }) { |
|
el._vov = el.style.visibility === 'hidden' ? '' : el.style.visibility |
|
if (transition && value) { |
|
transition.beforeEnter(el) |
|
} else { |
|
setVisibility(el, value) |
|
} |
|
}, |
|
mounted(el, { value }, { transition }) { |
|
if (transition && value) { |
|
transition.enter(el) |
|
} |
|
}, |
|
updated(el, { value, oldValue }, { transition }) { |
|
if (!value === !oldValue) return |
|
if (transition) { |
|
if (value) { |
|
transition.beforeEnter(el) |
|
setVisibility(el, true) |
|
transition.enter(el) |
|
} else { |
|
transition.leave(el, () => { |
|
setVisibility(el, false) |
|
}) |
|
} |
|
} else { |
|
setVisibility(el, value) |
|
} |
|
}, |
|
beforeUnmount(el, { value }) { |
|
setVisibility(el, value) |
|
} |
|
} |
|
|
|
function setVisibility(el, value) { |
|
el.style.visibility = value ? el._vov : 'hidden' |
|
} |
|
|
|
// just TRIGGER an animation! |
|
const vTrigger = { |
|
beforeMount(el, { value }, { transition }) { |
|
if (transition && value) { |
|
transition.beforeEnter(el) |
|
} |
|
}, |
|
mounted(el, { value }, { transition }) { |
|
if (transition && value) { |
|
transition.enter(el) |
|
} |
|
}, |
|
updated(el, { value, oldValue }, { transition }) { |
|
if (!value === !oldValue) return |
|
if (transition) { |
|
if (value) { |
|
transition.beforeEnter(el) |
|
transition.enter(el) |
|
} else { |
|
transition.leave(el, () => {}) |
|
} |
|
} |
|
}, |
|
} |
|
|
|
// set a css class given as argument |
|
const vCls = { |
|
beforeMount(el, { arg, value }, { transition }) { |
|
if (transition && value) { |
|
transition.beforeEnter(el) |
|
} else { |
|
setCls(el, arg, value) |
|
} |
|
}, |
|
mounted(el, { value }, { transition }) { |
|
if (transition && value) { |
|
transition.enter(el) |
|
} |
|
}, |
|
updated(el, { arg, value, oldValue }, { transition }) { |
|
if (!value === !oldValue) return |
|
if (transition) { |
|
if (value) { |
|
transition.beforeEnter(el) |
|
setCls(el, arg, true) |
|
transition.enter(el) |
|
} else { |
|
transition.leave(el, () => { |
|
setCls(el, arg, false) |
|
}) |
|
} |
|
} else { |
|
setCls(el, arg, value) |
|
} |
|
}, |
|
beforeUnmount(el, { arg, value }) { |
|
setCls(el, arg, value) |
|
} |
|
} |
|
|
|
function setCls(el, arg, value) { |
|
if (value) { |
|
el.classList.remove(arg); |
|
} else { |
|
el.classList.add(arg); |
|
} |
|
} |
|
</script> |
|
|
|
<template> |
|
<button @click="toggleShow()">toggle</button> |
|
<hr /> |
|
<transition> |
|
<div v-visible="show"> |
|
<h1>Hello v-visible!</h1> |
|
<p>This will affect the layout as normal.</p> |
|
</div> |
|
</transition> |
|
<hr /> |
|
<transition> |
|
<div v-show="show"> |
|
<h1>Hello v-show!</h1> |
|
<p>This will be removed from the layout.</p> |
|
</div> |
|
</transition> |
|
<hr /> |
|
<transition> |
|
<div v-trigger="show" :class="{invisible:!show}"> |
|
<h1>Hello v-trigger!</h1> |
|
<p>Same visible effect as <code>v-visible</code>, but actually <em>just</em> a trigger.</p> |
|
</div> |
|
</transition> |
|
<hr /> |
|
<transition> |
|
<div v-cls:invisible="show"> |
|
<h1>Hello v-cls!</h1> |
|
<p>Same visible effect as <code>v-visible</code>, but sets a given css class.</p> |
|
</div> |
|
</transition> |
|
<hr /> |
|
</template> |
|
|
|
<style> |
|
.v-enter-active { |
|
animation: fade-in 1s; |
|
} |
|
.v-leave-active { |
|
animation: fade-in 1s reverse; |
|
} |
|
@keyframes fade-in { |
|
from { |
|
opacity: 0; |
|
} |
|
to { |
|
opacity: 1; |
|
} |
|
} |
|
|
|
.invisible { |
|
opacity: 0; |
|
} |
|
</style> |