VibeJS - A Small JavaScript Library for Composing User Interfaces and Apps
Published: 2021-07-07 19:24:16

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qf08gg6r8cny0f7an7xb.jpg)
**[Go to Github ] (https://github.com/bretgeek/vibejs)**  to get VibeJS.
**[Visit VibeJS.com ](https://vibejs.com)**  for more info.


# VibeJS

**VibeJS** is a small JavaScript library for composing component based user interfaces and apps **OR** as a general purpose JQuery like utility library. 


## Features

* Small - currently under 16KB minified.
* Create self contained components for composing larger components and apps.
* Optional external access to the component.
* Rendered components receive built-in methods **(the Vibe)**.
* Easy familiar syntax with built-in chain-able DOM manipulation methods.
* Pass in external functions or plugin functions to your rendered components.
* Built-in Drag and Drop methods.
* Ability to set up custom observers on rendered components.
* Convert any element or HTML string to a **Vibe'd** element.
* Optionally use as a JQuery like utility library for getting work done. 
* And more ...


### If you think this is interesting, please hit that heart button!
* This open source project can use your help, please heart here or favorite on Github!


## Why another JS library?

 I was in need of a small component based library but wanted to know the internals of how one was built.

 I created for **VibeJS** for my own needs and in the spirit of open source, released it free of charge on Github. 

It is my hope it will be useful to anyone who needs it and hopefully encourage others to help with future improvements.

## Basic Usage

Getting started with **VibeJS** is easy. 

You can add **VibeJS** to an existing web page in a script tag (or use a bundler like Webpack).

 [See the Basic Usage at VibeJS.com ](https://vibejs.com) for more info on using Webpack.

* Add Vibe to your page before the closing body tag.

```javascript
<script src='https://yoururl.com/vibe.min.js'></script>

// Or from a CDN

<script src='https://cdn.jsdelivr.net/gh/bretgeek/vibejs@main/vibe.js'></script>
```



### Create a basic component

You create components much like would in React using a function.

A basic component function that doesn't do much would look like this:

* This would go in a script tag or external.js/bundle.js file.

```javascript
const aComponent = () => {

    const template = `<div>Hey, I am a component!</div>`;

    return {
    template: template,
    className: 'myComponent',
    }
}
```

### Render it

* To render the component to a page that contains an element with an id of **app** would look like this:

```javascript
const aRef = $vibe.render(aComponent, {
    to: '#app',
    className: 'renderedComponent',
});
```

That is an extremely basic component that doesn't do much.

## Lets Make a Component That Does a Little More...

The component above works but doesn't do a whole lot. Let us make another component that does do something.

In this next component we will add a click event to log a message to the console. 

Be sure to look at the additions in the code and read the code comments:

* Make the component with a function (again in a script tag or external.js/bundle.js):

```javascript
const myComponent = () => {

    const template = `<div>Hey, I am app!</div>`; // Your component's HTML as string template, can pass in variables too;

   // Just an example function (optional)

    const func = function say() {
        console.log('I am app')
    };

    // init runs automatically if it exists

    const init = function init(e) {
    console.log('I am an '+e);

    // can chain built-in e.$fns DOM methods!
    e.$css('cursor: pointer;').$text('I am new text');
  
    };


   // Another function but this time we will pass it in as an event handler

    const click = function click(e) {

   // target may or may not be "this" if template has nested elements
       console.log('clicked ' + e.target.tagName ); 

// In an Event "this" refers to the component and you can access $fn.func()
        this.$fn.func(this); 
    };


   // A state object (optional, pass in anything you want).
   // After making changes to state, state can be reverted to original saved in component's $origState

    const state = {x:1};


   // Render uses this return object to add these to the component

   return {
        template: template,
        className: 'myComponent',
        init: init,
        fn: {
            func: func
        },
        events: {
            click: click,
        },
        state: state
    }
}
```
### Render it

Render the component to a DIV with an id of "app" and save a reference to it as "myRef"

* In an html file:

```javascript
// somewhere in your html

<div id='app'> </div>
```

* In a script tag after vibe.js:

```javascript
// className, state, events, plugins (like fn of component) etc. can be added here too

const myRef = $vibe.render(myComponent, {
    to: '#app',
    position: 'append',
    className: 'renderedComponent',
});
```

* You can render a component as many times as you want using different reference names.

* Components **can render other components** too (hint:  modules/import/export within components).

## The Vibe

You might be wondering what the meaning of **Vibe** is in **VibeJS**. 

It's a feature!

Components can be completely self contained however, after rendering a component it becomes **vibed**.

A **vibed** component exposes all it's built-in methods. 

You can interact with the component (inside the component itself or externally) and call these built-in methods using the reference ("myRef" in this case) like:

```javascript
// Call built-in Vibe methods to change the css and the text etc. (chain-able).

myRef.$css('display: inline-block').$text('Hey hey!');


// Call the internal function you declared in the component

myRef.$fn.func();



// Tack on more events with $on

myRef.$on('click', function(){ console.log('my Text is: '+this.$text()) });
```

* There are lots more vibe methods (read the code!)


## Vibe Any Element!

**Vibing** isn't limited to components. You can also **Vibe** any existing element. 

Here is how you do that!

* Use normal JavaScript to select an existing div with a class name ".myDiv".

```javascript
const aDiv = document.querySelectorAll('.myDdiv')[0];
```

* **Vibe** it via render...
```javascript
const aDivRef = $vibe.render(aDiv);

// Use it!

console.log('div existing text is ' + aDivRef.$text());

aDivRef.$text('I am new text.');
```

* ***Note that when vibing existing elements, since there is no "component functions to pass in", properties for className, state, events and plugin (if any) must be passed in via this render object.


## Components that Render Components

When building large scale JavaScript apps using modules or bundling tools like Webpack, **import and exports** are essential to making your app easy to work with on a team of developers as well as help to keep your code organized. 


Components that render other components work the same way. You must export and import the assets you want to use.

The following is how you would render a component from another component.

* If App1 is in in js/App1.js and is prefixed with export like:

```javascript
export const App1 = () => {

    const template = `I am an App1 component!`;

    return {
    template: template,
    className: 'App1',
    }
}
```

* App2 can import and render App1 from a method like init or any other method with an import:


```javascript
import {App1} from '/js/App1.js';

    const App2 = () => {

    const template = `App2 rendered an App1 component!`;

    const init = function init(e) {  // "e" here is $self and you can also pass in $self here.

    // Render App1 to App2

    const App1Ref = $vibe.render(App1, {
    to: e,
    position: 'append',
    });

    // change App1's text to show its working

    App1Ref.$text('App1 component imported to App2');

    };// End init

    return {
    template: template,
    init: init,
    className: 'App2',
    }
}
```
In the example above **App2** imports **App1** and renders it via **App2**'s init method. 

The real power of this comes when rendering components to other components via Events! 

Which means you can render new components via click, touch etc. add infinity. 

Todo list anyone?

## In Summary

I hope you enjoyed this article about my little open source JS library. 

I hope it will inspire someone of you out there to give it a try, dig in to the code and recommend improvements. 

For those who do try it, I can't wait to see what you build!

There are a lot more things **VibeJS** can do and I hope to cover those things in future posts. 

Give me a follow so you don't miss out on those.

Until then, keep **Vibe'n**!

Visit **[ VibeJS.com ](https://vibejs.com)**  for future changes and docs (lots to do!).