Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

The process of transferring a custom directive from Vue 2 to Vue 3 is largely the same, but there are a few differences in the implementation due to changes in the Vue 3 API. Here is an example of how to transfer a directive that detects clicks outside of an element from Vue 2 to Vue 3:

Vue 2 Implementation:

Vue.directive('click-outside', {
  bind: function(el, binding) {
    el.clickOutsideEvent = function(event) {
      if (!(el == event.target || el.contains(event.target))) {
        binding.value(event);
      }
    };
    document.body.addEventListener('click', el.clickOutsideEvent)
  },
  unbind: function(el) {
    document.body.removeEventListener('click', el.clickOutsideEvent)
  }
});

Vue 3 Implementation:

const clickOutside = {
  beforeMount: function(el, binding) {
    el.clickOutsideEvent = function(event) {
      if (!(el == event.target || el.contains(event.target))) {
        binding.value(event);
      }
    };
    document.body.addEventListener('click', el.clickOutsideEvent)
  },
  unmounted: function(el) {
    document.body.removeEventListener('click', el.clickOutsideEvent)
  }
};

const app = createApp(...);
app.directive('click-outside', clickOutside);

As you can see, the main differences between the two implementations are:

  • bind and unbind have been replaced with beforeMount and unmounted.
  • The directive is now defined as a separate object, rather than being registered directly on the Vue instance.
  • The createApp function is used to create the Vue instance, rather than the new Vue syntax.