Home

Awesome

vuecket

Power of Vue.JS married with magic of Apache Wicket

Vuecket allows to be reactive on frontend and backend without coding of REST services.

Content

  1. Progress and Plans
  2. Guiding Principles
  3. Enabling Vuecket
  4. Association of Wicket and Vue Components
  5. Server-side methods
  6. Subscribing to Vue Events
  7. Watch data changes
  8. Data Fibers

Other documentation:

Current Progress and Plans

Guiding Principles

Vuecket idealogy following the following principals:

  1. Be declarative, not imperative
    • You can use VueJS 3rd party libraries and get benefits out of Vuecket even without modifying them
    • In a similar way, you can use 3rd party Apache Wicket component and just by adding VueBehavior (Behavior provided by Vuecket) you enable Vuecket benefits
  2. Provide 80% of functionality Out Of the Box, but do have good extension points for the remaining 20%

As you can see, btw, both Vue.Js and Apache Wicket fit this Guiding Principles as well.

Enabling Vuecket

Add the following dependency into your pom.xml:

<dependency>
   <groupId>org.orienteer.vuecket</groupId>
   <artifactId>vuecket</artifactId>
   <version>${project.version}</version>
</dependency>

If you are using SNAPSHOT version, please make sure that the following repository is included into your pom.xml:

<repository>
	<id>Sonatype Nexus</id>
	<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
	<releases>
		<enabled>false</enabled>
	</releases>
	<snapshots>
		<enabled>true</enabled>
	</snapshots>
</repository>

Association of Wicket and Vue Components

To start using of Vuecket power you should associate your server-side component(Wicket) and client-side component(Vue.js). You have 2 ways how to do that:

Vue.js components can be also defined by:

Annotations

The following code will allow you to make from common Wicket Label component which supports Markdown

@VueNpm(packageName = "vue-markdown", path = "dist/vue-markdown.js", enablement = "Vue.use(VueMarkdown)")
public class VueMarkdown extends Label {

	public VueMarkdown(String id, IModel<?> model) {
		super(id, model);
	}

	public VueMarkdown(String id, Serializable label) {
		super(id, label);
	}

	public VueMarkdown(String id) {
		super(id);
	}
	
	@Override
	protected void onComponentTag(ComponentTag tag) {
		tag.setName("vue-markdown");
		super.onComponentTag(tag);
	}
}

Check the following annotations: @VueJson, @VueFile and @VueNpm

Directly on Wicket Componet

add(new VueComponent<String>("app")
      .setVueDescriptor("{ data: { message : 'Hello Vue'}}")
);

add(new VueComponent<String>("app2")
      .setVueDescriptor(new PackageResourceReference(HomePage.class,"HomePage.app2.vue"))
);

add(new Label("app3").add(new VueBehavior(new VueJsonDescriptor("{ data: { message : 'Hello Vue'}}"))));

Server-side methods

Vuecket can work transparantly for Vue code. But you can add more spice by invoking server based methods from your Vue code.

There are 2 ways how you can use Vuecket server methods:

Example from test Vuecket application:

add(new VueComponent<Object>("app5") {
	@VueMethod("count")
	public void updateCountModel(IVuecketMethod.Context ctx, int count) {
		IVuecketMethod.pushDataPatch(ctx, "server", "Hello from server #"+count);
	}
}.setVueDescriptor("{ data: { count : 0, server: 'Hello from client side' }}"));
<div>
	<h1>App #5</h1>
	<div wicket:id="app5">
		<button @click="count++; vcInvoke('count', count)">Clicked {{count}} times</button>
		{{ server }}
	</div>
</div>

Subscribing to Vue Events

It might be helpful to subscribe to particular Vue Events on server side. To do that you can use @VueOn and @VueOnce annotations for methods which needs to be invoked if event occur on client side. Example:

@VueOn("increase")
public void showIncrease(int count) {
	System.out.println("On Increase called. Recieved count = "+count);
}
<button @click="$emit('increase', count)">Test Emit</button>

Watch data changes

In the similiar way you can subscribe server side method to changes of data on client side by using @VueWatch annotation

@VueWatch("count")
public void countChanged(Integer newCount, Integer oldCount) {
	System.out.println("Count changed from "+oldCount+" to "+newCount);
}
<button @click="count++">Clicked {{count}} times</button>

Data Fibers

Data fiber is a way to synchronize data between server side and browser. There are different types of data-fibers

Example:

//Value of this model will be initially load to all connected clients and then kept update upon changes
private static final IModel<String> HELLO_MODEL = Model.of("Hello from server");
...
VueComponent<Object> app6 = new VueComponent<Object>("app6", HELLO_MODEL)
				.setVueDescriptor("{ data: { text : 'Hello Vue'}}")
				.addDataFiber("text");  // <===Pay attention to this call. It binds default IModel to 'text' data fiber
app6.add(new VueMarkdown("markdown", ""));
add(app6);
<div>
	<h1>App #6</h1>
	<div wicket:id="app6">
		<textarea v-model="text"></textarea>
		<vue-markdown wicket:id="markdown" v-bind:source="text">Application 6</vue-markdown>
	</div>
</div>