/ nativescript

NativeScript and Vue.js

I'm a big fan of NativeScript as it allows me to make native mobile applications with ease. My go-to front end framework is Angular, so naturally I use NativeScript Angular quite a bit... but I've been experimenting with Vue.js in a lot of the work I'm doing, so NativeScript Vue was intriguing. Let's make our own NativeScript application that gets data from a REST API:

New Application

Ensure you've got the NativeScript CLI installed, and then we can create a project as usual, but with the nativescript-vue-template

# Install the NativeScript CLI
npm install nativescript -g

# New NativeScript Vue project
tns create NSVue --template nativescript-vue-template

# Change directory
cd NSVue

# Run on iOS
tns run ios

Initialising Vue

Let's start off by removing everything inside of app.js and rebuilding it from the ground up. We can start by importing Vue, http and adding an instance property for our http library. I've also added a small template that consists of our page and an action bar.

const Vue = require('nativescript-vue/dist/index');
const http = require('http');

Vue.prototype.$http = http;

new Vue({
    template: `
    <page>
        <action-bar title="Users"></action-bar>
    </page>
    `
}).$start()

Data

Inside of our Vue instance, we can now define the (simplified) model that we'll be displaying on screen.

  data: {
    users: [
      {
        id: 1, name: "Leanne Graham", username: "Bret", email: "[email protected]"
      }
    ]
  },

Template

With all the above in place, we can then update our template to display a single user on screen. I've added a ListView and a corresponding template that simply displays the name, username and email:

template:
  `
  <page>
    <action-bar title="Users" class="action-bar"></action-bar>
    <stack-layout>
      <list-view :items="users">
        <template scope="user">
          <stack-layout class="list-item">
            <label :text="user.name"></label>
            <label :text="user.username"></label>
            <label :text="user.email"></label>
          </stack-layout>
        </template>
      </list-view>
    </stack-layout>
  </page>
  `,

Methods: API

Now, let's add a method to our Vue instance that allows us to get a list of users from an API:

  methods: 
  {
    getData() {
      this.$http
        .getJSON(`https://jsonplaceholder.typicode.com/users`)
        .then(response => {
          this.users = response.map(
            user => {
              return {
                name: user.name,
                username: user.username,
                email: user.email
              };
            }
          );
        })
        .catch(err => {
          console.log("err.." + err);
        });
    }

Lifecycle Hook

That same method can then be called on the created() lifecycle hook. This allows us to call the getData method when our instance is created.

  created() {
    this.getData();
  },

Finish this off with a tiny amount of CSS and we're good to go!

list-view {
    height: 100%;
}

.list-item {
    margin: 20px;
}

Tada! Here's our project:

nativescript-vue

Our final file looks like this:

const Vue = require('nativescript-vue/dist/index');
const http = require('http');

Vue.prototype.$http = http;

new Vue({
  data: {
    users: [
      {
        id: 1, name: "Leanne Graham", username: "Bret", email: "[email protected]"
      }
    ]
  },
  template:
  `
  <page>
    <action-bar title="Users" class="action-bar"></action-bar>
    <stack-layout>
      <list-view :items="users">
        <template scope="user">
          <stack-layout class="list-item">
            <label :text="user.name"></label>
            <label :text="user.username"></label>
            <label :text="user.email"></label>
          </stack-layout>
        </template>
      </list-view>
    </stack-layout>
  </page>
  `,
  created() {
    this.getData();
  },
  methods: 
  {
    getData() {
      this.$http
        .getJSON(`https://jsonplaceholder.typicode.com/users`)
        .then(res => {
          console.log(res);
          this.users = res.map(
            user => {
              return {
                name: user.name,
                username: user.username,
                email: user.email
              };
            }
          );
        })
        .catch(err => {
          console.log("err.." + err);
        });
    }
  }
}).$start()

Paul Halliday

Progress Telerik Developer Expert. Course author with students in 110+ countries. BSc (Hons) Computer Science @ UoS. Google accredited Mobile Site professional.

Read More