This is a removed section from my book: Building & Deploying Crypto Trading Bots with Rails & Go. You can signup to receive up updates here.

Getting Started

Setting Up the Development Environment

This section will briefly cover installing the required development environment for building our front end with Node and VueJS. A quick summary of what you will need is:

If you already have the tools and required software, feel free to skip over the instructions below

MacOS
Follow the steps below to get your development environment setup for developing the front end.

  1. Follow the nvm installation guide
  2. Install node version v10.11.0 (nvm install 10.11.0)
  3. The installation script should print out a set of exports to add to your .bashrc, or .zshrc configuration to load nvm, be sure to add this, and reload your terminal
export NVM_DIR="$HOME/.nvm"[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
NVM installation

4. Set your node version to v10.11.0 (nvm use 10.11.0)

5. Verify your node version is correct (node -v)

If you run into any issues reference the troubleshooting section for MacOS.

6. Install yarn via Homebrew (brew install yarn)

7. Use yarn to install the v.3.10.0 vue-cli tools globally (yarn global add @vue/cli@3.10.0)

8. Verify your vue-cli installation (vue -V or vue create test)

Linux (Ubuntu 18.04)

Follow the steps below to get your development environment setup for developing the front end.

  1. Follow the nvm installation guide

2. Install node version v10.11.0 (nvm install 10.11.0)

3. The installation script should print out a set of exports to add to your .bashrc, or .zshrc configuration to load nvm, be sure to add these, and reload your terminal window

export NVM_DIR="$HOME/.nvm"[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

4. Set your node version to v10.11.0 (nvm use 10.11.0)

5. Verify your node version is correct (node -v)

If you run into any issues reference the troubleshooting section for Linux.

6. Follow the yarn installation guide for Debian / Ubuntu systems (you will need to import the GPG keys and add the APT repository to your system before running apt install yarn)

7. Use yarn to install the v.3.10.0 vue-cli tools globally (yarn global add @vue/cli@3.10.0)

8. Verify your vue-cli installation (vue -V or vue create test)

Setting Up the App Environment

With our dependencies installed we can begin creating the application. To create the initial project use the vue-cli tool  installed in the last section. The vue-cli is a powerful tool that gives end users the ability to create new applications with custom or default configuration setups at a granular level. For our purposes, we will just take the default set up:

vue create test-application

Vue CLI v3.10.0
┌───────────────────────────┐
│  Update available: 4.1.2  │
└───────────────────────────┘
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint) 
  Manually select features

Vue CLI v3.10.0
✨  Creating project in ./book/test-application.
🗃  Initializing git repository...
⚙  Installing CLI plugins. This might take a while...

yarn install v1.9.2
info No lockfile found.
[1/4] 🔍  Resolving packages...

✨  Done in 17.28s.
🚀  Invoking generators...
📦  Installing additional dependencies...

yarn install v1.9.2
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...

success Saved lockfile.
✨  Done in 91.28s.
⚓  Running completion hooks...

📄  Generating README.md...

🎉  Successfully created project test-application.
👉  Get started with the following commands:

 $ cd test-application

If you change directory into your newly created app, you will see vue-cli sets up our directory structure, package.json and linter settings. Turning to the package.json, the default configuration has provided us with BabelJS (a transpiler tool used to convert ECMAScript 2015+ code into a backwards compatible JavaScript in current and older browsers) and ESLint (a tool that analyzes your code against standard code style) dependencies as well as a host of useful commands like serve, build, lint, etc.

The starter application is a good place to make an initial commit, but, if you check the git log you will see that the vue-cli has already taken care of this for us. In that case, we can

Digging In

Vue Instances

The entry point of our application is a file called main.js which creates an instance of a JavaScript object called Vue that runs our app.

These "Vue instances" are the work horses of a Vue application, and in particular, an application's root Vue instance. The root instance is created by supplying an existing DOM element of a web page to the Vue constructor for it to mount onto. Similar to React, Vue uses this element as anchor to instantiate a virtual DOM containing information describing what kind of elements should be rendered on the page. As application state changes, the Vue instance "reacts" to these changes, and updates the real DOM by creating, removing or mutating elements in the tree. The mounting DOM element is supplied as a property (called el) as a part of a broader "options" object passed to a Vue constructor.

If you've worked in JavaScript you might be familiar with this convention. Because JavaScript is dynamic developers tend to use objects as arguments to methods and constructors in order to namespace arguments (as properties of the object) and avoid confusion. For example:

// Options argument - default is 10
function countTo(options = { limit: 10 }) {
	const limit = options.limit
	for (var i = 0; i< limit; i++) {
		//.. console log to the screen
	}
}

countTo({ limit: 12 })

We see the same pattern with the Vue constructor below:

<!-- An HTML file --> 
<div id='app'>
   <!-- Vue mounts on this div --> 
</div>

// A JS file
const app= new Vue({
	// The options object
	el: 'app'
})

This options object can contain a variety of properties spread across six categories including: Data,  Miscellaneous, Lifecycle Hooks, Assets, Composition, and DOM. You can read about them in Vue documentations, but, the common ones are those in data (e.g. data, computed, props, methods, etc), DOM (e.g. template, el, etc) and lifecycle hooks (e.g. created, mounted, updated, etc).

You can see what the default app created by our main.js file looks like by running yarn serve and navigating to http://localhost:8080 with the browser.

The default VueJS app on localhost:8080

Components & Single File Components

Vue works on the principle of reusable visual components. Each component is a Vue instance which is nested under the root Vue instance. These instances manage and reactively render their virtual DOM to the real DOM according to changes in their state and or  the state of their children.

A Vue app is a composition of components each with their own state, that is mutated according to lifecycle hooks, methods, and event listeners (more on those later). While these components can be declared in pure JavaScript, and passed HTML templates as strings, this is not the preferred way to work. Instead developers use .vue files.

Vue's "single-file components" or .vue files have their own scoped HTML, JavaScript and CSS that compile into Vue instances. In specific, these files have three sections (template, script and style) containing the components HTML, JavaScript and CSS, that define the Vue instance properties and are added to the virtual DOM and rendered as desired. You can see an example of a single-file component by opening App.vue. This file might seem bit strange but we'll take it section by section.

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

The first template section is the Vue instance's template HTML. In pure JavaScript this would be a string literal passed as a property of the options object like new Vue({ template: Hello })). It is an HTML-based template syntax that allows you to declaratively bind the rendered DOM to the underlying Vue instance's data.

The script section is where the remainder of instance properties are defined and exported for compilation. However, the App component is not doing much here besides registering a subcomponent called HelloWorld that is bound and rendered in the template section above.

Finally, the style section is used for defining CSS related to a component's visual appearance. It can be on a global or scoped in level which is pretty handy. Let's open the HelloWorld component to get another look into what is going on.

HelloWorld.vue

Below is an excerpt of HelloWorld.vue component that is rendered by App.vue.

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    // ... rest of template code
    </p>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
// ... scoped css
</style>
HelloWorld.vue

In the template section we can see familiar HTML elements like div, p, etc, in addition to an expression {{ msg }} which is bound to the value in the Vue instance's props or data (depending on declaration). Let's take a look at the script section for more insight.

The script section shows that the msg variable is declared from props which is data passed down by the parent component (e.g. App). This variable is bound to the template, and renders whatever value provided by the parent component. This variable could alternatively be declared from a Vue instance's data function instead. If you remove the props definition, and replace it with data as seen below, the Vue app will re-render and look exactly the same.

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

So what's the difference between props and data? For starters, data is a component's in-memory and private storage for values, whereas, props is data passed from parent to child components. Both are "reactive" in that if either change, the component will re-render. However, data is mutable storage and props is not intended to be. That is, props are a mechanism of one way data flow and communication from the parent to child components, and as such are not advised to mutate (if they are Vue will send a warning message to the console). Both props and data are linked to the rendered DOM through the Vue instance but have different utilities.

Methods & Directives

The starter app is, unsurprisingly,  dull but we can make it interesting by adding some methods and event listeners. Component methods are defined in the methods property of a Vue instance, and in single-file components this also lives in the <script> section. Defined methods are bound and available to the template section. They act like standard Javascript methods to mutate data and react to interactions performed on the rendered DOM.

Methods (and data) can be glued to the DOM via directives which are attributes added to templates that allow components to listen to events emitted by the DOM and Vue. These typically take the form of v-on:click or v-on:<event> (Vue also has helpful @  short forms, @click, for these) and embedded into HTML. For example:

<button v-on:click="onClickFunction()">Click Me</button>

Directives can also enable conditional (v-if) or iterative (v-for) logic that allows you to render components under certain circumstances or multiple times. Let's add a button to the default template and a method to increment a count value stored in data in the HelloWorld.vue component

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p> {{count}}</p>
    <button v-on:click="increment()"> 
      Count + 1
    </button>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.$data.count +=1 
    }
  }
}
</script>

Vue is full of these directives, features and functions and we will see more of as you work through it, but those should be enough basics to get you started!


If you enjoyed this post consider checking out my upcoming book "Building & Deploying Trading Bots in Rails". You can signup to receive up updates here.

Kind thanks to Karolina Grabowska for the cover art.