# Integrating With JS Components
# Using JS Components in Java
Vue GWT allows us to make our nice Java Components. But the Vue.js ecosystem is vast, it would be a shame if we couldn't take advantage of existing JS Components. Well let's see how we can do that!
TIP
This examples declare Vue components directly in the index.html.
For this to work, you need Vue loaded before you declare them.
You can use VueGWT.initWithoutVueLib()
in your GWT app, and a JS dependency to Vue in your index.html instead.
# Instantiating a JS Component in Java
Let's say we have the following JS Component declared in JavaScript:
window.FullJsComponent = Vue.extend({
template: "<div>I Come In Peace From the JS World.</div>"
});
Let's try see how to instantiate it in Java:
// First, we get the VueJsConstructor from Window
VueJsConstructor vueJsConstructor = ((JsPropertyMap<VueJsConstructor>) DomGlobal.window).get("FullJsComponent");
// We can then manipulate it exactly like
// our VueJsConstructor generated from our Java Components
IsVueComponent myFullJsComponent = vueJsConstructor.instantiate();
myFullJsComponent.vue().$mount("#fullJsComponent");
And here it is live:
# Declaring our JS Component Interface
Our first JS component was rather easy, let's say we now have this one:
window.FullJsWithMethodsComponent = Vue.extend({
template: "<div>My Value: {{ value }}. My Value x2: {{ multiplyBy2(value) }}</div>",
data: function () {
return {
value: 10
}
},
methods: {
multiplyBy2: function (value) {
return value * 2;
}
}
});
We would like to manipulate our instances from Java. For this we need some kind of Java definition.
Let's do it for our FullJsWithMethodsComponent
:
@JsComponent("FullJsWithMethodsComponent")
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Function")
public class FullJsWithMethodsComponent implements IsVueComponent {
public int value;
public native int multiplyBy2(int value);
}
Looks pretty similar to our Java Components, but there a few key differences:
- We use the
@JsComponent
annotation instead of@Component
- We have to use the
@JsType
to tell GWT this is a nativeFunction
- Our JS methods are declared as
native
in our Java class. We don't need to provide their implementations, they will come from the JS Component. - You only need to declare what you want to interact with in the Class. If you don't need to call some methods or access some attributes from Java, you don't have to declare them.
Because of the @JsComponent
annotation, Vue GWT generates a VueComponentFactory
class for us, just like with our Java components.
So we can do:
FullJsWithMethodsComponent myComponent = FullJsWithMethodsComponentFactory.get().create();
myComponent.vue().$mount("#fullJsWithMethodComponent");
JsTools.log(myComponent.value); // 10
JsTools.log(myComponent.multiplyBy2(25)); // 50
myComponent.value = 15; // Change the value in the instance of our Component
Bellow is the component instantiated, without any change to it's original value. You can interact with it in the console, it's just a regular Vue instance.
# How does @JsComponent
find the existing JS Component?
You may have noticed we also pass "FullJsWithMethodsComponent"
to our @JsComponent
annotation.
This is used to find the Js Component on window
.
So if you put @JsComponent("MyVueLib.MyComponent")
, it will link your JsComponent
class to: window.MyVueLib.MyComponent
.
# What if the JS library exposes a Component options object?
Some libraries like Vue ChartJS exposes a Component options object and not a Component Constructor.
You can use the same method, and Vue GWT will automatically create a Vue Component constructor from those options for you.
The only change is you have to tell GWT that the instance is an Object
and not a Function
:
@JsComponent("VueChartJs.Line")
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
public class AbstractVueLineChartComponent implements IsVueComponent
# Using Our JS Component in a Java One
You can use your JS Component just like the Java ones.
Which means you can also pass them to the @Component
annotation as local components:
@Component(components = FullJsWithMethodsComponent.class)
You can then simply use it in your Java Component template:
<div>
<full-js-with-methods></full-js-with-methods>
</div>
# Extending a JS Component
We can also extend JS Components (this is required for some Vue plugins for example).
# Using our Java Components in JS
It's possible to get our Java Components to use them in a JS application.
The VueGWT
global object has a getJsConstructor
that allow you to retrieve the JS Constructor for your Java Component.
Beware this object only exist after your GWT app loading (which is async).
const MyJavaComponent = VueGWT.getJsConstructor("com.package.MyJavaComponent");
const vm = new MyJavaComponent();
vm.$mount("#javaComponent");
MyJavaComponent
is just a regular Vue Constructor, you can use it anywhere, you can extend it etc...