ddraper

Content Distribution with Slots in Vue.js

Blog Post created by ddraper on Dec 22, 2016
This is a personal blog post that is primarily intended for tracking my own learning rather than provided to the Alfresco Community for educational purposes. However if you find it useful, informative or have any comments on it then please comment below.

 

At the end of my last post I'd got my Node.js based application set up and was accessing data from an Alfresco Repository over axios and rendering it in a simple Vue.js component. I now wanted to explore building out some interaction with the data that was being loaded and I decided to make a start by building some basic pagination controls. You can view the state of my project at the time of writing by checking out this tag.

 

After several years working on Aikau I find it very difficult to break away from the practice of writing small, re-usable and abstract components. I've also spent a lot of time thinking about how I would implement list handling if I had the chance to do it again. I think that I got a lot write with the way I implemented the AlfList widget in Aikau in that it was predominantly used just for managing the list state but I wish that I'd used it to encapsulate all the controls that would update the  list so that I could make better use of event bubbling. Therefore I naturally took this as an opportunity to investigate that approach.

 

In an ideal world I'd love to get to the point where you can just build up a page using custom elements (i.e. Web Components) and Vue.js refers to this as "Content Distribution" (which is called "transclusion" in Angular). It would be great if you could build an Alfresco client directly into an HTML page with custom elements similar to this:

<alf-list>
  <alf-list-toolbar>
    <alf-list-paginator></alf-list-paginator>
  </alf-list-toolbar>
  <alf-list-view>
  </alf-list-view>
</alf-list>

 

However, I've gotten so far (with Vue.js) is what you see in my code currently:

<alf-list>
  <template scope="props" slot="before-view">
    <alf-list-toolbar :list="props.list"></alf-list-toolbar>
  </template>
  <template scope="props" slot="view">
    <alf-list-view :list="props.list"></alf-list-view>
  </template>
</alf-list>

 

The additional template elements act as a way in which properties can be passed from parent component to child component assigned to a slot. Now whilst this does work it feels less intuitive and seems to result in another problem in that custom events can't be emitted from child component to parent component without the aid of a "global event bus".

 

The implementation I currently have does work and the use of one-way data flow works really nicely in that the pagination buttons emit an event to page forwards or backwards and the list component requests new data which when set will automatically cause the pagination controls and view to refresh.

 

 

Despite the current code working I'm going to switch to a more standard development approach where each component simply references another directly in it's template rather than trying to use slots. I might revisit the content distribution option later and investigate how other frameworks address it.

Outcomes