Post

Auto import Vue directives from directory

Harianto van Insulinde
none
/lib/directives/
  index.js
  v-focus.js
/plugins/
  directives.js
nuxt.config.js

Nuxt File Structure

Basic implementation

from: Custom Directives

js
// Register a global custom directive called `v-focus`
Vue.directive('focus', {
  // When the bound element is inserted into the DOM...
  inserted: function (el) {
    // Focus the element
    el.focus()
  }
})

Then in a template, you can use the new v-focus attribute on any element, like this:

html
<input v-focus>

Modular v-focus

js
module.exports = {
  // When the bound element is inserted into the DOM...
  inserted: function (el) {
    // Focus the element
    el.focus()
  }
}

File: /lib/directives/v-focus.js

js
// Register a global custom directive called `v-focus`
Vue.directive('focus', require('./lib/directives/v-focus'))

Then in a template, you can use the new v-focus attribute on any element, like this:

html
<input v-focus>

Auto import directives

js
// https://webpack.js.org/guides/dependency-management/#require-context
const requireComponent = require.context(
    // Look for files in the current directory
    '.',
    // Do not look in subdirectories
    false,
    // Only include "v-" prefixed .js files
    /v-[\w-]+\.js$/
)

const directives = {}
// For each matching file name...
requireComponent.keys().forEach(fileName => {
    // Get the component config
    const componentConfig = requireComponent(fileName)
    // Get the PascalCase version of the component name
    const componentName = fileName
        // Remove the "./_v-" from the beginning
        .replace(/^\.\/v-/, '')
        // Remove the file extension from the end
        .replace(/\.\w+$/, '')

    // Globally register the component
    directives[componentName] = componentConfig.default || componentConfig
})

export { directives }

File: /lib/directives/index.js

js
module.exports = {
  // When the bound element is inserted into the DOM...
  inserted: function (el) {
    // Focus the element
    el.focus()
  }
}

File: /lib/directives/v-focus.js

js
import Vue from 'vue'
import { directives } from './lib/directives'
Object.entries(directives).forEach(([key, value]) => Vue.directive(key, value))

Main JavaScript

Nuxt config and implementation

js
import Vue from 'vue'
import { directives } from '../lib/directives'
Object.entries(directives).forEach(([key, value]) => Vue.directive(key, value))

File: /plugins/directives.js

js
module.exports = {
    plugins: [
        '~/plugins/directives'
    ]
}

Snippet: /nuxt.config.js

How to add more directives

Store your files in /lib/directives.
Prepend your file with v- so your file look like this: v-*directive-name*.js.

Example

none
/lib/directives/
  index.js
  v-focus.js
  v-attach-my-animation.js

File Structure

For example v-attach-my-animation.js.
Directive name would be: attach-my-animation, then your template would be:

html
<div v-attach-my-animation>
</div>

Always kebab-case your JavaScript files for Vue directives, a reminder that HTML is case insensitive!