At this point, we have a structured approach for creating new Vue.js components and consolidating them into a single module export. Awesome! Next, we'll bundle the components into a plugin to be registered on a Vue instance.
Remember that the Vue CLI creates a main.js
entry point file in the root of the /src
directory during the project initialization. Usually, that's used as the entry point for a new Vue application. We'll modify this to create the plugin.
If you're landing on this post without reading the series introduction, jump there first.
main.js
entry point
Starting off, let's remove the generated code. We'll replace with the differences below.
// main.js
- import Vue from 'vue'
- import App from './App.vue'
- Vue.config.productionTip = false
- new Vue({
- render: h => h(App),
- }).$mount('#app')
+ import * as components from './components'
+
+ const ComponentLibrary = {
+ install(Vue, options = {}) {
+ // components
+ for (const componentName in components) {
+ const component = components[componentName]
+
+ Vue.component(component.name, component)
+ }
+ }
+ }
+
+ export default ComponentLibrary
+
+ if (typeof window !== 'undefined' && window.Vue) {
+ window.Vue.use(ComponentLibrary)
+ }
The file should look like:
// main.js
import * as components from './components'
const ComponentLibrary = {
install(Vue, options = {}) {
// components
for (const componentName in components) {
const component = components[componentName]
Vue.component(component.name, component)
}
}
}
export default ComponentLibrary
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.use(ComponentLibrary)
}
Let's step through this ๐.
Import the components from
src/components
. This will grab the components from the exports inindex.js
. That's the file that imports(collects) the components that we want to include in the library.Now, we'll create the Vue plugin and expose an
install
method. According to the Vue plugin documentation:
A Vue.js plugin should expose an install method...The method will be called with the Vue constructor as the first argument, along with possible options
In the
install
method, iterate through the imported components and assign each component to theconst component
. ThecomponentName
is used as a key get the component out of thecomponents
object.Register each component with
Vue.component()
. Thecomponent.name
is the name attribute from the component and thecomponent
as the component. When the plugin is registered in a Vue project, our components will be globally available.
In the above, componentName
is not the same as component.name
.
- Export the component library plugin as the default. This allows for importing into another file as
import ComponentLibrary from ...
syntax:
import Vue from 'vue'
import ComponentLibrary from './main.js'
Vue.use(ComponentLibrary)
...
- Lastly, auto-register the plugin in situations where a Vue instance exists in the window and a module system is not used. We'll give this a test when we publish the library to a content delivery network (CDN) and include it on a page after the included Vue tag. This is covered in the Vue Getting Started Guide and is an option when adopting Vue into an existing application that may not use a build system.
Currently, the above set up does one thing - registering components. That's all we need it to do now but there are different patterns for plugin creation and the library entry point, main.js
, in this case.
A few examples include:
- Adding directives, filters, and mixins
- Adding instance properties with
Vue.prototype
- Importing style dependencies
- Merge user-defined options into the plugin registration with
options = {}
The outline prescribed in the Vue documentation for writing a plugin is:
// 1. add global method or property
Vue.myGlobalMethod = function () {
// some logic ...
}
// 2. add a global asset
Vue.directive('my-directive', {
bind (el, binding, vnode, oldVnode) {
// some logic ...
}
...
})
// 3. inject some component options
Vue.mixin({
created: function () {
// some logic ...
}
...
})
// 4. add an instance method
Vue.prototype.$myMethod = function (methodOptions) {
// some logic ...
}
Source: https://vuejs.org/v2/guide/plugins.html#Writing-a-Plugin
One last tip
Also, always remember to populate a name
attribute in your components if using the Vue.component
and component.name
approach above. The registration will throw an error if component.name
doesn't exist.
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'name-of-your-component' // :point_left:
}
</script>
<style></style>
Give your components a name โ๏ธ
Next up, tightening the feedback loop plus a hint of amazing documentation with VuePress ๐.
Subscribe to get my latest content by email -> Newsletter
Top comments (1)
Hello! been enjoying these posts so far, but I have a question.
In the install function, if you register every component as the global component, wouldn't it make the end-user's app's final bundle bigger than it needs to be?
If the library contains hundreds of vue components for example, and an end-user is only using around a dozen of them, I'm not sure wheather the rest of the components would be tree-shaken later.