Vue.directive('collapsible', { bind: function (el, binding) { el.classList.add('collapse'); el.classList[binding.value ? 'add' : 'remove']('show'); el.transitionDuration = 350; }, update: function (el, binding) { if (binding.oldValue !== binding.value){ if (binding.value) { setTimeout(function () { el.classList.remove('collapse'); const height = window.getComputedStyle(el).height; el.classList.add('collapsing'); el.offsetHeight; el.style.height = height; setTimeout(function () { el.classList.remove('collapsing'); el.classList.add('collapse'); el.style.height = null; el.classList.add('show'); }, el.transitionDuration) }, 0); } else { el.style.height = window.getComputedStyle(el).height; el.classList.remove('collapse'); el.classList.remove('show'); el.offsetHeight; el.style.height = null; el.classList.add('collapsing'); setTimeout(function () { el.classList.add('collapse'); el.classList.remove('collapsing'); }, el.transitionDuration) } } } });