How to create a npm package with multiple vue directives? Or should I create one package per directive?

269 Views Asked by At

I am able to create an npm package by exporting a single vue directive in the src/index.js file. But how can I create a package that lets you use multiple vue directives. I am not able to export two vue directives in the same index.js file.

export default Vue.directive('directive1', {
  inserted: function (el, binding, vnode) {
    el.addEventListener('mouseup', (e) => mouseup(e, el, _data))
    el.addEventListener('mousedown', (e) => mousedown(e, el, _data))
    el.addEventListener('mousemove', (e) => mousemove(e, el, _data))
    setDraggerOffset(el, _data)
  }
})

export default Vue.directive('directive2', {
  inserted: function (el, binding, vnode) {
    el.addEventListener('mouseup', (e) => mouseup(e, el, _data))
    el.addEventListener('mousedown', (e) => mousedown(e, el, _data))
    el.addEventListener('mousemove', (e) => mousemove(e, el, _data))
    setDraggerOffset(el, _data)
  }
})
2

There are 2 best solutions below

0
On BEST ANSWER

You are trying to export two defaults. A default means you can get the value by just saying import MyPack from 'path/to/package'. You need to export constants, and destructure where you are importing. Learn more here

In the package

export const vD1 = Vue.directive('directive1', {
  ...
})

export const vD2 = Vue.directive('directive2', {
  ...
})

Wherever you're importing:

import { vD1, vD2 } from 'path/to/package';
0
On

Check Vue Guide: Writing one plugin, we can follow this guide to develop our directives, then allow the users to activate specific directives by 2nd parameters=options.

Like below demo (assuming export myDirectives, and only enable directive1):

let myDirectives = {}
let _defaultDirectives = ['directive1', 'directive2']
myDirectives.directive1 = {
  inserted: function (el, binding, vnode) {
    el.addEventListener('mouseup', (e) => mouseup(e, el, _data))
    el.addEventListener('mousedown', (e) => mousedown(e, el, _data))
    el.addEventListener('mousemove', (e) => mousemove(e, el, _data))
    console.log('directive1', `setDraggerOffset(el, _data)`)
  }
}

myDirectives.directive2 = {
  inserted: function (el, binding, vnode) {
    el.addEventListener('mouseup', (e) => mouseup(e, el, _data))
    el.addEventListener('mousedown', (e) => mousedown(e, el, _data))
    el.addEventListener('mousemove', (e) => mousemove(e, el, _data))
    console.log('directive2', `setDraggerOffset(el, _data)`)
  }
}

myDirectives.install = function (Vue, options) {
  let selectedDirectives = (options && options.directives) || _defaultDirectives
  selectedDirectives.forEach((directive) => 
    Vue.directive(directive, this[directive])
    // this[directive + 'Definition'] = Vue.directive(directive, this[directive])
  )
}

// export default myDirectives

// Vue.use(myDirectives) // default option is register both directive1 and directive 2
Vue.use(myDirectives, {directives: ['directive1'] }) // register directive1 only

// console.log('Definition', myDirectives.directive1Definition, myDirectives.directive2Definition)

new Vue({
  el: '#app'
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <span v-directive1></span>
  <span v-directive2></span>
</div>