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>
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',
}
}
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',
});
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
}
}
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>
- 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',
});
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()) });
- 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];
- 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.');
- ***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',
}
}
- 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',
}
}
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)
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.
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!
String template for CSS is good. I'll try it.
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}
)Be sure to put backticks around the grey areas above.. for some reason Dev.to is removing them from my reply.
Don't worry I know that. Plus, that is markdown.
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.