Rendering FrintJS Apps with Vue.js

Fahad Heylaal
FrintJS
Published in
3 min readDec 4, 2017

FrintJS itself is agnostic of any rendering library. The core is primarily focused on managing its dependencies with providers, so that other tools and integrations can form around it.

While the main frint package takes care of creating Apps with providers, we have other packages like frint-react handling React.js integration. Same way, we also have frint-vue that enables you to render your Vue.js components using similar API to that of React’s integration.

Rendering with Vue.js alone

Before getting into FrintJS, let’s first create and render a Component with Vue.js alone.

We will be using JSX for the examples below. Let’s say we have a basic component that prints out “Hello World”:

import Vue from 'vue';const MyComponent = {
render(h) {
return <p>Hello World</p>;
},
};
const vm = new Vue({
...MyComponent,
el: 'root',
});

The code above assumes, you have an element in your DOM with ID root:

<div id="root"></div>

Rendering with frint-vue

Before rendering, we need to create a FrintJS App first:

import { createApp } from 'frint';const App = createApp({
name: 'MyApp',
});

Now we will let our App know about our Vue.js component, by setting it as a provider with the name component:

import { createApp } from 'frint';const MyComponent = {
render(h) {
return <p>Hello World</p>;
},
};
const App = createApp({
name: 'MyApp',
providers: [
{
name: 'component',
useValue: MyComponent,
}
,
{
name: 'foo',
useValue: 'foo value here',
},
],
});

Since our App is clearly defined by now, we can proceed with rendering it to DOM with Vue.js:

import { render } from 'frint-vue';const App = createApp({ ... });const app = new App();
render(app, {
el: 'root',
});

We basically imported the render function from our frint-vue package, and called it by providing the App instance, and additional options specifying where to render it in the DOM.

Accessing providers in Vue.js components

The frint-vue package follows similar API as found in frint-react. You can still access the FrintJS App instance from your components using our observe higher-order component, from which you can then get your desired providers.

Synchronous props:

If the props are not changing over time:

import { observe } from 'frint-vue';const MyComponent = {
props: ['appName', 'foo'],
render(h) {
return (
<div>
App Name: {this.appName}
Foo: {this.foo}
</div>
);
},
};
export default observe(function (app) {
return {
appName: app.getName(),
foo: app.get('foo'),
};
})(MyComponent);

Streaming props:

Where props is a stream expressed with an RxJS Observable:

import { observe } from 'frint-vue';
import { interval } from 'rxjs/observable/interval';
import { map } from 'rxjs/operators/map';
const MyComponent = {
props: ['interval'],
render(h) {
return (
<div>
Interval: {this.interval}
</div>;
);
},
};
export default observe(function (app) {
return interval(1000).pipe(
map(x => ({ interval: x }))
);
})(MyComponent);

The code above demonstrates props as a steam using RxJS lettable operators. Ultimately, we are streaming a prop-compatible object from the returned Observable here.

You can also use our streamProps helper function to combine values from various sources into a single props observable:

import { observe, streamProps } from 'frint-vue';
import { interval } from 'rxjs/observable/interval';
const MyComponent = { ... };export default observe(function (app) {
return streamProps()
// sync props
.set('appName', app.getName())
.set('foo', app.get('foo')
// where source is an Observable
.set(
interval(1000),
x => ({ interval: x })
)
// generate a combined Observable of props
.get$();
})(MyComponent);

Your MyComponent will now receive both appName, foo, and interval as props. The appName and foo props will stay the same, but interval will keep incrementing every second, which will trigger a re-render of your Vue.js component.

Further reading:

Find us on Twitter and Gitter if you have any questions!

--

--

Fahad Heylaal
FrintJS

Maker of things · JavaScript · RxJS · ReactJS