Extending a Component Library using Vuex
Tags: vue, vuex
Published: 2020-12-07 16:27:15

---
title: Extending a Component Library using Vuex
published: true
description: 
tags: vue, vuex
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/15ex2ilcmoobubyeemj5.jpg
---


At [FeldsparTech](https://www.feldspartech.com/) we are working on a no-code platform called [Atman](https://www.feldspartech.com/atman). Atman's UI is a component library that works as a standalone application or can be embedded into another application to enable quick no-code workflows.

One of our goals is to allow granular control over our components. If this only meant rendering - we would build [Renderless components](https://adamwathan.me/renderless-components-in-vuejs/). However, we also want the consuming application to be able to override, modify and augment behavior.

The approach we have chosen to achieve this goal is to use a [Vuex](https://vuex.vuejs.org/#what-is-a-state-management-pattern) store.

- Prerequisite: Both the consuming application and the library should import and use Vuex.
- We first need to dynamically register our library as a module in the application's store. This is possible through the [registerModule](https://vuex.vuejs.org/guide/modules.html#dynamic-module-registration) method

```javascript
if(!this.$store.hasModule("ourlibrary")){
   this.$store.registerModule("ourlibrary", store);
}
```

- Methods that need to be customizable are implemented as actions in a vuex module. Within the action, the behavior could vary:
    - If we want the consuming application to be able to ***override*** behavior, the *action* first checks if a global *action* is available and invokes it. If not, the *action* proceeds to perform the default logic specified in the library.
    - If we want the consuming application to ***augment*** behavior, the module *action* first performs the internal logic and then invokes the global *action* (or vice versa) to perform any augmentation as necessary.

![https://dev-to-uploads.s3.amazonaws.com/i/15ex2ilcmoobubyeemj5.jpg](https://dev-to-uploads.s3.amazonaws.com/i/15ex2ilcmoobubyeemj5.jpg)

### Overriding behavior example

```javascript
 overriddenMethod({dispatch},params){
    if(this._actions["overriddenMethod"]) {
       return dispatch("overriddenMethod", params, {root:true});
    } else {
      //Default behavior
    }
}
```

### Augmenting behavior example

```javascript
 augmentedMethod({dispatch},params){
     let response;
     /*
        Internal logic which updates `response`
        ...
     */
    if(this._actions["augmentedMethod"]) {
       globalResponse = dispatch("augmentedMethod", params, {root:true});
    }
    /*
        Update `response` with `globalResponse`
    */
    return response;
}
```

This pattern is quite powerful. For instance, you can now even allow the consuming application to entirely replace a particular nested component with one of its own.

Here, the vuex action functions as a [Factory](https://en.wikipedia.org/wiki/Factory_method_pattern). Now you can customize the logic as per your needs. The Overriding approach will entirely replace default component. The Augmentation approach will allow the consuming application to add business-specific components you may not want in the library.

## Dynamic Component in the Library

```jsx
<template>
    <component v-if="currentComponent" v-bind:is="currentComponent"></component>
</template>
<script>
export {
    //...
    async mounted() {
      this.currentComponent = await this.$store.dispatch(`<module>/deriveComponent`)
    }
}
</script>
```

## Action in Library's store

```javascript
deriveComponent(context, params) {
    let currentComponent;
    //augment or override as per your requirements
    return currentComponent
    
}
```

## Resources I found useful during this exercise

- Github template to create a vuetify component library
{% github [https://github.com/mitevpi/vuetify-component-lib-template](https://github.com/mitevpi/vuetify-component-lib-template) %}
- A step-by-step series by siegerts on how to create a Vue JS component library
{% link [https://dev.to/siegerts/creating-a-vue-js-component-library-part-i-introduction-2o9f](https://dev.to/siegerts/creating-a-vue-js-component-library-part-i-introduction-2o9f) %}

Also cross-posted on [Medium](https://feldspar-tech.medium.com/extending-a-component-library-using-vuex-965b45f0bfcc)