Hello!
GET /speaker/info
{
"name": "Igor Randjelovic",
"location": "Budapest",
"occupation": "I study software engineering",
"twitter": "@igor_randj",
"website": "igor-randjelovic.com",
}
Vue.js
NativeScript
What is NativeScript?
Open Source framework for building truly native mobile applications.
NO DOM
NO WebViews
Just
PURE AWESOME
Native Views
YES PLEASE!
What is Vue?
A JavaScript MV framework
A bit like Angular 1
but only the good things
Vue is SIMPLE!
Learn it in less than a week
Two main units in Vue
Components
Directives
Pretty much everything is a component
for low-level DOM access
A simple Vue component
// Define a new component called todo-item
Vue.component('todo-item', {
template: '<li>This is a todo</li>'
})
<ol>
<!-- Create an instance of the todo-item component -->
<todo-item></todo-item>
</ol>
A simple Vue directive
// Register a global custom directive called v-focus
Vue.directive('focus', {
// When the bound element is inserted into the DOM...
inserted: function (el) {
// Focus the element
el.focus()
}
})
<!-- Use the focus directive on an input element -->
<input v-focus>
Vue is very powerful
Simple when you need it to be
Scales very well with larger applications
First-Party ecosystem
VueRouter
+
Vuex
How does Vue come into play with NativeScript?
+
= ?
Vue 1.x is DOM dependent :(
Vue 2.x is DOM independent! :)
Virtual DOM is awesome!
This brings me to my next point...
NativeScript-Vue
+
An integration between NativeScript and Vue
In short, it's a custom renderer implementation for Vue
NativeScript
NativeScript-Vue
Vue
The only difference is the template*
* and the way you start the Vue app
const Vue = require('nativescript-vue');
const app = new Vue({
template: '',
data: {},
methods: {}
// ...
// everything is the same!
});
// The only difference is the following line
app.$start();
Let's build an app!
Step 1: Initialize project
$ tns create hello-nativescript-vue --template tns-template-blank
Installing tns-template-blank
+ tns-template-blank@3.2.0
added 4 packages in 1.182s
up to date in 0.125s
Project hello-nativescript-vue was successfully created.
Step 2: Delete files we will not need
and clear out app.js
$ cd hello-nativescript-vue/app
$ rm bundle-config.js home -r
$ echo "" > app.js
Step 3: Let's add nativescript-vue
$ tns plugin add nativescript-vue
$ # or
$ npm install --save nativescript-vue
$ # or
$ yarn add nativescript-vue
Step 4: Let the fun begin
// app.js
const Vue = require('nativescript-vue');
const app = new Vue({
template: `<page></page>`,
});
app.$start();
Step 5: Run the application
$ tns run android
Yay!
Not very exciting is it?
Let's add an action bar and a label
// app.js
const Vue = require('nativescript-vue');
const app = new Vue({
template: `
<page>
<action-bar title="I 😍 NativeScript-Vue"></action-bar>
<stack-layout>
<label text="Hello World"></label>
</stack-layout>
</page>
`,
});
app.$start();
How about some tabs?
<page>
<action-bar title="I 😍 NativeScript-Vue"></action-bar>
<stack-layout>
<tab-view>
<!-- First Tab -->
<tab-view-item title="Awesome Tab">
<label text="This is an awesome tab! 😇"></label>
</tab-view-item>
<!-- Second Tab -->
<tab-view-item title="Emoji Tab 🤓">
<label text="This is an emoji tab 😂"></label>
</tab-view-item>
</tab-view>
</stack-layout>
</page>
Make them dynamic?!
<page>
<action-bar title="I 😍 NativeScript-Vue"></action-bar>
<stack-layout>
<tab-view>
<!-- Dynamically populated tabs -->
<tab-view-item v-for="tab in tabs" :title="tab.title">
<label :text="tab.content"></label>
</tab-view-item>
</tab-view>
</stack-layout>
</page>
const app = new Vue({
template: `...`,
data: {
tabs: [
{ title: 'First Tab', content: 'This is the first tab' },
{ title: 'Second Tab', content: 'This is the second tab' },
{ title: 'Third Tab', content: 'This is the third tab' },
]
}
});
We can add a tab header
<page>
<action-bar title="I 😍 NativeScript-Vue"></action-bar>
<stack-layout>
<tab-view>
<tab-view-item v-for="tab in tabs" :title="tab.title">
<stack-layout>
<stack-layout height="100"
:backgroundColor="tab.bgColor">
<label :text="tab.title" class="tab-title"></label>
</stack-layout>
<!-- Will add something cool here -->
</stack-layout>
</tab-view-item>
</tab-view>
</stack-layout>
</page>
Let's add a List View
...
<stack-layout>
<stack-layout height="100"
:backgroundColor="tab.bgColor">
<label :text="tab.title" class="tab-title"></label>
</stack-layout>
<!-- Will add something cool here -->
<list-view :items="s(tab.listSource)">
<template scope="contact">
<stack-layout class="contact-list-item">
<label :text="contact.name"
class="contact-name"></label>
<label :text="contact.phone"
class="contact-phone"></label>
</stack-layout>
</template>
</list-view>
</stack-layout>
...
After some cleanup
const app = new Vue({
template: `...`,
data: {
tabs: [
{
title: 'Recent',
listSource: 'recentContacts',
bgColor: '#00aafc'
},
{ title: 'All', ... },
{ title: 'Favorites', ... },
]
contacts: [
{
name: 'John Doe',
phone: '123 456 789',
recent: true,
favorite: true
},
// ...
],
},
// Next slide
// ...
});
... continued
const app = new Vue({
// ...
// Next slide
computed: {
recentContacts() {
return this.contacts.filter(c => c.recent);
},
favoriteContacts() {
return this.contacts.filter(c => c.favorite);
}
},
methods: {
s(source) {
return this[source];
}
}
});
Let's add a modal
<list-view :items="s(tab.listSource)" @itemTap="openContact">
methods: {
s(source) {
return this[source];
},
openContact(e) {
const contact = e.item;
this.$showModal({
template: `<!-- On next slide -->`
})
}
}
Define the modal template
<stack-layout width="90%" height="40%"
style="background-color: #fff;">
<stack-layout style="height: 150; background-color: #00aafc;">
<label text="${contact.name}" class="tab-title"
style="margin-top: 80;"></label>
</stack-layout>
<label text="Phone" style="margin: 10; font-size: 12;"></label>
<label text="${contact.phone}" style="margin-left: 20;"></label>
</stack-layout>
template: `
`
Let's see what we
made so far.
We want to be able to add new users
const ContactForm = {
template: `
`,
}
<stack-layout width="90%" style="background-color: #fff;">
<stack-layout style="height: 150; background-color: #00aafc;">
<label :text="isNew ? 'Add Contact' : 'Edit Contact'" class="tab-title"
style="margin-top: 80;"></label>
</stack-layout>
<label text="Name" style="margin: 10; font-size: 12;"></label>
<text-field v-model="_contact.name" hint="Contact Name"></text-field>
<label text="Phone" style="margin: 10; font-size: 12;"></label>
<text-field v-model="_contact.phone" hint="Contact Phone"></text-field>
<grid-layout columns="*, *" height="40">
<button col="0" text="Cancel" @tap="cancel"></button>
<button col="1" text="Save" @tap="save"></button>
</grid-layout>
</stack-layout>
const ContactForm = {
template: `
`,
}
Add the rest
const ContactForm = {
props: {
contact: {
default() {
return { name: '', phone: '', recent: false, favorite: false }
}
},
isNew: Boolean
},
template: `...`,
created() { this._contact = Object.assign({}, this.$props.contact) },
data() {
return {
_contact: {},
};
},
methods: {
save() {
this.$modal.close(this._contact);
},
cancel() {
this.$modal.close();
},
}
};
Now we just use it
<action-bar title="I 😍 NativeScript-Vue">
<action-item android.systemIcon="ic_menu_add" @tap="showForm()"></action-item>
</action-bar>
showForm(contact) {
const isNew = !contact;
const options = {
context: {
propsData: {
contact: contact,
isNew: isNew,
}
}
}
this.$showModal(ContactForm, options).then((res) => {
if (res) {
if (isNew) {
this.contacts.push(res);
} else {
// update existing contact
for (const prop in res) {
contact[prop] = res[prop]
}
}
}
});
}
We can edit contacts
And create new contacts
It's tedious to write your templates as string literals...
But there are .vue files to make your life easier
Single File Components
<template>
<!-- Your components template goes here -->
</template>
<script>
// Your JavaScript goes here
</script>
<style>
/* Your CSS goes here */
</style>
<style scoped>
/* Your scoped CSS goes here */
</style>
AwesomeComponent.vue
You can use them in nativescript too!
tns create nativescript-vue-app --template https://github.com/tralves/nativescript-vue-rollup-template
And finally, let me show you NativeScript Sidekick
An extension to the NativeScript CLI
Manage plugins
Debug apps using chrome devtools
Build apps locally and in the Cloud
Let me show you
NativeScript-Vue
NativeScript Slack Community
In the #vue channel
Thank You!
@igor_randj
A new Vue for NativeScript
By Igor Randjelovic
A new Vue for NativeScript
- 4,171