DEV Community

bretgeek
bretgeek

Posted on • Updated on

VibeJS - A Small JavaScript Library for Composing User Interfaces and Apps

Alt Text
Go to Github to get VibeJS.
Visit 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 for more info on using Webpack.

  • Add Vibe to your page before the closing body tag.
<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>
Enter fullscreen mode Exit fullscreen mode

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.
const aComponent = () => {

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

    return {
    template: template,
    className: 'myComponent',
    }
}
Enter fullscreen mode Exit fullscreen mode

Render it

  • To render the component to a page that contains an element with an id of app would look like this:
const aRef = $vibe.render(aComponent, {
    to: '#app',
    className: 'renderedComponent',
});
Enter fullscreen mode Exit fullscreen mode

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):
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
    }
}
Enter fullscreen mode Exit fullscreen mode

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:
// somewhere in your html

<div id='app'> </div>
Enter fullscreen mode Exit fullscreen mode
  • In a script tag after vibe.js:
// 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',
});
Enter fullscreen mode Exit fullscreen mode
  • 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:

// 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()) });
Enter fullscreen mode Exit fullscreen mode
  • 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".
const aDiv = document.querySelectorAll('.myDdiv')[0];
Enter fullscreen mode Exit fullscreen mode
  • Vibe it via render...
const aDivRef = $vibe.render(aDiv);

// Use it!

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

aDivRef.$text('I am new text.');
Enter fullscreen mode Exit fullscreen mode
  • ***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:
export const App1 = () => {

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

    return {
    template: template,
    className: 'App1',
    }
}
Enter fullscreen mode Exit fullscreen mode
  • App2 can import and render App1 from a method like init or any other method with an import:
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',
    }
}
Enter fullscreen mode Exit fullscreen mode

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 for future changes and docs (lots to do!).

Top comments (7)

Collapse
 
ashishk1331 profile image
Ashish Khare😎 • Edited

Looks like a derivative of Vuejs, just more focused and tiny. Thanks for sharing!
Just need to know that does it works on the shadow dom concept or just a simple element creator from pure js.

Collapse
 
bretgeek profile image
bretgeek

Hey there thanks for reading and taking the time to comment!

No shadow dom needed! You can create any element you want.

However I recommend using standard elements. The reason is, custom elements will not pass validators (at least I do not know of a way). This is not Vibe's fault though:).

Also instead of using the shadow dom to prevent things like css bleed, each component can set it's own CSS with something like:

myRef.$css('position: absolute; display: inline-block;') etc.

You can even use string templates to pass in variables:

myRef.$css(height: ${num}px; display: inline-block; ).

And of course you could create style tags as components with rules to style components that match data-attributes that you define. But the $css method is just easier in my opinon.

It's also not a derivative of Vuejs. It is its own thing. There are no vue-if type of attributes for the elements or anything like that.

You are right, it is small but it I think it gives you the freedom to do what you want especially if you just want to drop in Vanilla JS to your components!

Heck ,you don't even have to create components at all if you don't want since you can "vibe" any element:)

I hope you give it a try. If you do, let me know how it goes!

Collapse
 
ashishk1331 profile image
Ashish Khare😎

String template for CSS is good. I'll try it.

Thread Thread
 
bretgeek profile image
bretgeek

Awesome!

You could even store your complete CSS in something like:

const cssvar = color: blue; display: block; width: 50px; ;

Which can span multiple lines if you want (because of the backticks).

then do:

myRef.$css(${cssvar})

Thread Thread
 
bretgeek profile image
bretgeek

Be sure to put backticks around the grey areas above.. for some reason Dev.to is removing them from my reply.

Thread Thread
 
ashishk1331 profile image
Ashish Khare😎

Don't worry I know that. Plus, that is markdown.

Collapse
 
efpage profile image
Eckehard

If you like new approaches on web programming, please check out DML. This features an approach based on the principles of Object Orientation. There is a post about the initial thoughts behind it here "What´s wrong with webdesign...".

There is a strong trend to say, that one approach is better than the other. That´s kind of stupid! Frameworks are tools to do a job. As there are different tasks, there should be different tools too.