Single Page Applications and kdb+: Vue

8 June 2021 | 5 minutes

By Stephen Trainor

This blog post is the fourth of a series, which demonstrates how different front-end technologies can be used with kdb+. The technology discussed in this post is called Vue (also known as vue.js). Vue is an open-source JavaScript (JS) framework which was first released in 2014. Version 3.0 was released in September 2020, which is covered in this post. A distinguishing feature of Vue is that HTML, JS and CSS can be stored in a single .vue file, rather than the traditional approach of maintaining JS and HTML files separately.

The Single-Page Application (SPA) discussed in this blog contains two tabs. The first is a calendar, which demonstrates cell editing and pagination. The second doesn’t contain any functionality and is just present to demonstrate URL routing for this technology.

Common SPA Features

Websockets and Promises are used throughout all of the technologies in this series, and are discussed in the first entry, which focuses on React and is posted on this link. It also provides a brief introduction to what a Single-Page Application is.

Vue

Setting up

  • Download source code from Github
  • Download npm
  • Run npm update in the terminal from the vueProject directory, to install dependencies from package.json (bringing the project size to around 130MB)
  • Run downloaded startV.bat and startQ.bat files – if you aren’t using C:\q\w64, startQ will require editing
  • View from a browser: http://localhost:8080/

Components and data-flow

The philosophy of Vue is to have .vue components, each containing HTML, JS and scoped-css, which neatly organise styling and dependencies.

Data can be passed from parent components to child components as props, and child components emit events which can trigger callbacks in the parents. Prop-types can be used to document components and provide warnings in the console if an incorrectly typed prop is provided to the component.

Vue also allows developers to write reactive code, in which HTML is only re-rendered if the associated refs are updated..

Directives

Vue comes with many predefined directives, which allow the developer to simply generate the desired HTML. Some directives used in this project are explained below. The full list can be found here.

  • v-if
    • Renders an element if the expression evaluates to true
  • v-else
    • Renders an element if the previous v-if evaluates to false
  • v-for
    • Renders an element one time for each item in the provided data
  • v-on:click
    • Calls a function when the element is clicked
  • v-on:blur
    • Calls a function when the element loses focus
  • v-bind
    • Binds an attribute to the element. Eg a dynamic class
  • v-model
    • Creates a two-way data binding on an element or component. Eg a checkbox which updates a boolean variable when it is clicked

“@” can also be used as a shorthand for “v-on:”, but is potentially less readable.

The below directives were also considered for this project, but were unsuitable as the use-case was to detect events anywhere on the page, whereas these directives only detect events within the element they’re attached to.

  • v-on:wheel
    • Calls a function when the user scrolls
  • v-on:keydown.ip/down/left/right
    • Calls a function when the user presses the directional keys

Libraries

primevue is a UI component library which was used for the TabMenu and ProgressSpinner components

vue-devtools is a browser extension which allows developers to inspect vue components and data using Chrome dev tools

vue-router enables predefined url paths to load corresponding JS files

Sample Project


Vue SPA – Consists of a calendar with editable cells, and a separate tab to demonstrate routing

Structure

  • main.js
    • App.vue
      • TabMenu
      • router-view
        • Calendar.vue
        • OtherTab.vue

main.js contains component registration and creates the application instance.

App.vue contains the TabMenu to display the two tab buttons, and router-view, which renders the selected tab.

Rendering a table

 

kdb+

 

In the calendar tab, a table with 8 rows is displayed on the front end, and refreshes as the user scrolls:

.cal.getCalendar:{[index]
  t:update hiddenIndex:i from cal;
  select ["j"$index,8] from t
};

 

Vue

<table v-else class="table">
<thead>
<tr>
<th v-for="(column,i) in calendarKeys" v-bind:class="this.headerWidth(column)" :key="i">{{formatHeader(column)}}</th>
</tr>
</thead>
<tbody>
<tr v-for="(row,index) in calendar" :key="index">
<td v-bind:contenteditable="isEditable(colName)" v-bind:class="this.highlightDate(calendar[index][colName], colName)" v-on:blur="editRow(index, colName, $event)"
v-for="(colName) in calendarKeys" :key="colName">{{this.formatCell(calendar[index],colName)}}</td>
</tr>
</tbody>
</table>

Editing a table

 

kdb+

 

When the user edits a cell in the calendar tab, .cal.editRow is called. It formats the text provided by the user, and overwrites that table cell in memory using a functional select.

 

.cal.editRow:{[index; kolName; kolVal]
  index:"j"$index;
  kolName:`$kolName;
  t:`cal;
  kolType:type (value t)[kolName];
  //Only include numbers in number fields
  if[kolType in "h"$5+til 5; kolVal@:where kolVal in .Q.n,"-."];
  //Cast to the appropriate datatype
  kolVal:(neg kolType)$kolVal;
  if[kolType=0h; kolVal:(enlist; kolVal)];
  if[kolType=11h; kolVal:enlist kolVal];
  //update kolName:kolVal from cal where i=index
  ![t; enlist(=;`i;index); 0b; (enlist kolName)!enlist kolVal];
}

Vue

 


editRow: function(index, colName, event){
let text = event.target.innerText;
index+=this.index;
this.qPromise(".cal.editRow",[index, colName, text]).then(this.postEditRow).catch(this.error)
},

 

Conclusion

 

Vue is an SPA framework which is simple to set up and can provide a fast and responsive browsing experience. This blog discussed its benefits, such as built-in directives, two-way data-binding and custom components, and should serve as a suitable introduction to getting started with Vue and coupling it with kdb+.

The front and back-end code outlined above are available in GitHub on this link

Demo kdb, the fastest time-series data analytics engine in the cloud








    For information on how we collect and use your data, please see our privacy notice. By clicking “Download Now” you understand and accept the terms of the License Agreement and the Acceptable Use Policy.