Damián Pumar

← Back to blog

Published on December 31, 2023 by Damián Pumar

If for some reason you need to reuse a vue component in a directive I would like to share with you the best way I found to do it.

Scenario 🍿

I had vue component used to copy text into many components 👇

//components/CopyCode.component.vue
<template>
  <base-action-tooltip class="button" tooltip="Copied">
    <a href="#" @click.prevent="copy(code)">
      <svgicon name="copy" width="16" height="16" />
    <a>
  </base-action-tooltip>
</template>

<script>
import "assets/icons/copy";
export default {
  props: {
    code: {
      type: String,
      required: true,
    }
  },
  methods: {
    copy(code) {
      this.$copyToClipboard(code);
    }
  }
};
</script>

Problem 🤔

For some reason I needed to reuse the same behavior in a vue directive, as you know directives are a bit limited to reuse components and functions, but I found a way to reuse any component. I know that reusing components in a directive is not a good practice, but sometimes it is necessary to do it because you will have to rewrite all the vue code in vanilla javascript, and sometimes that would be a lot of work, right?

Solution 🤓

Let me explain how you can reuse a vue component inside a directive. In my case, I need to add the copy functionality in a vue directive called “copy-code”.

import Vue from "vue";
import CopyCodeComponent from "./CopyCode.component.vue";

Vue.directive("copy-code", {
  bind: (element, _, node) => {
    //...
    const copyCode = Vue.extend(CopyCodeComponent);
    const instance = new copyCode({
      propsData: { code },
      $copyToClipboard: node.context.$copyToClipboard,
    });

    instance.$mount();
    container.appendChild(instance.$el);
    //...
  },
});

In a bind function you have the element that is using your directive, but in the node object you have the Vue component with the application context.

You just need to extend the component with Vue and instantiate it with all the props you need and pass the context props if you are using custom plugins, global states, etc.

Hopefully it will be useful for you 🤞

Bye 👋

Written by Damián Pumar

Something wrong? Let me know 🙏

← Back to blog