VueJS basics

his is the second part in a series of articles I am writing about how I used VueJS to build a static site.

Assumptions for this article

  • You have NodeJS 8.x installed with npm.
    • You can verify your installation by running these commands in a PowerShell window,
node --version
npm --version
  • You have some knowledge of CLI-based bootstrapping, and development.
  • You are using some sort of a web development IDE. I highly recommend VS Code.

Setup

You’ll want to get the official Vue CLI first. Be sure to install the latest stable release of the CLI. There is a beta version out there. At the time of this writing, 3.0 is still in beta so you can refer to the README for the 2.x version on the master branch. Then, run:

npm install -g vue-cli
vue init webpack my-project

Go through the prompts in your shell and complete the boilerplate project setup. These are my settings:

? Project name static-site
? Project description A Vue.js project
? Author Blog Author <author@blog.com>
? Vue build runtime
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner karma
? Setup e2e tests with Nightwatch? Yes
? Should we run `npm install` for you after the project has been created? (recommended) npm

You’ll notice that I used the word webpack in the command to create the project. That’s the name of the webpack template in the CLI. The CLI will automatically create the necessary webpack base configuration with all the loaders, extractors etc.
Once you are done with the setup, you can start-up your dev server for local development using:

npm run dev

You can access the local server using http://localhost:8080. This is it for setup. For most static sites, I don’t anticipate any changes in the base webpack config. So you don’t have to meddle with it at all, not even when you are ready to build a distribution package.

Basics

The sweet spot, in my opinion, for developing using Vue is, its single-file components. Everything that a component needs, the HTML template, the script, and the CSS (or SCSS, if you are living in the 21st century), is in the same file. This encourages you to split your site (or app) into simpler components that do only one thing. It encourages you to use the parent-child communication pattern effectively by way of props.

I won’t go over everything from the excellent documentation on VueJS’ docs site. But I will go over some of the basics, that I think are important before I explain how I built Net Your Problem.

Declarative Rendering

This is just a fancy way of saying, HTML in; HTML out. There is no special language for you to learn here. Of course, this doesn’t do much other than render the view (the HTML).

Open the App.vue file from the project you setup using the CLI and look at the content within the enclosing <template> tag.

and then in main.js:

All this is doing is, creating a new instance of a Vue app, and then binding the app instance to the root view, which is an element with the ID value “app”. As you can see, in App.vue, this is our <div> tag.

OK. But wait. How did Vue know where to look for an HTML element inside the App.vue component. Take a look at the “render” property in the statement for creating a new instance of a Vue app. Its value is an arrow function that accepts a callback function as a parameter. The callback function expects a Vue component to be passed to it. This render function is what kicks-off the render-ing of all child components when you start composing components from the parent component.

Data binding, conditional rendering and loops

A very important building block for any site, application. I am pretty sure almost every single site, web app out there uses conditional rendering and repeated elements all over.

Let’s modify the App.vue like this:

Now, reload the page. You should see the message Hello, World! right below the logo. If you change the value of the showMessage property from true to false, then you should see the message disappear. This was made possible because of the directive v-show. You can read more about conditional rendering and the other directive called v-if. There is an important performance difference between the two.

Let’s add a repeated element. Modify the App.vue’s template contents like this:

If the page hasn’t refreshed, refresh it, and you should see the additions. The condition items.length > 0 is satisfied since the items array has a non-zero size.  We only used a single <li> tag in the template, however, the final result has two of those. That’s because of the v-for directive. You can read more about it in the list rendering section of the guide.

Routers

Web sites, and web apps use URLs to send the user to new sections of a page, or to completely different pages. Routers are used to load/unload components as the user navigates your site/app. Depending on how you structure your site, you may or may not want to use a router at all. It isn’t necessary if you don’t have complex sections in your site, and you don’t need to orchestrate showing and hiding these sections appropriately.

But let’s walk-through it real-quick. If you recall in App.vue, there is a tag called <router-view/>. This is a special tag, which Vue recognizes as the output of a user navigation. That is, when the user navigates somewhere, the Vue system places the content of the new destination in its place.

Have a look at the router/index.js

That is it for some of the basics. I highly recommend reviewing the introduction to Vue’s concepts. You can read about them here.

Advertisements

What?! I can use HTML/Javascript/CSS for native mobile apps?

Well, not exactly. All you will be doing is writing a web app wrapped inside a webview that is “packaged” as a native app. As you may have read about the several articles online about using HTML/Javascript for mobile app development. Well, I am not going to talk about the different ways to do this. I am going to show you how we do it my company using PhoneGap. Before I start talking about PhoneGap I must let you know that the other worthy alternatives to native app development are Adobe Flex (supports iOS, Android, Blackberry), Titanium Appcelerator and then there is appMobi’s XDK which is a Chrome extension that allows you to develop an app right out of your browser; what a way to start developing an HTML5 app huh? Well, I have never tried it but it looks cool (and somewhat confusing) though.

The way PhoneGap works is it allows you to write an application using HTML5/JS/CSS3. The resources are then packaged as assets to a WebView based application. So, the app actually runs using a browser but the user wouldn’t or shouldn’t know the difference (if done right). The problem with using PhoneGap is that HTML5 spec is not completely stable yet and Android is one of the worst platforms for HTML5 development due its fragmented nature. There are over 900 “different kinds” of devices in the market that run Android OS in some form and factor which is exactly the problem because there is no standard spec whatsoever!! You have to account for the several different problems with these devices when writing an application using a spec that is first incomplete and second each browser has proprietary implementation of unfinished specs. So, there is always something that doesn’t work.

However, there are some annoying problems, for example, using an iframe in your app will screw with the native copy/paste functionality and the soft keyboard will stop responding to user input until it is closed and reopened. Another problem with Android phones is with the CSS3 transform3d which causes problems with the “native” android library and crashes the app when transform3d is used on a page containing input text box. So, after solving these problems you will see that you only need to know HTML and Javascript to develop a simple app. Granted you will need to write some PhoneGap plugins to solve some platform specific problems but they are all easy to do.

Then there is the infamous android transform3d bug with password boxes which appMobi’s jqMobi solved using the oldest trick in the book. A clever fix I should say. I will not reveal the fix here you should check out there source code and look at the passwordbox control to see what they have done. Once you do you would probably say “I knew that” well it did not occur to you, did it? Kudos to jqMobi for bringing that out!

Then there is the problem of using a javascript framework to do the dirty work for you. We were first using jQuery and that did not go well. Performance was poor. It was terrible. If I was not working for my company I would not even use the app past the installation, it was that bad. The thing about jQuery is it has a lot of backward compatibility for IE6 and other older browsers. When you know that you are only developing for Webkit why do you want to use a framework that has support for other browsers? When I realized this fact and took it upon myself to swap out the javascript framework with something much lighter and meant for Webkit I came across Zepto. Porting from jQuery to Zepto meant I had to look at what was missing. The good news about Zepto is that it has a jQuery style syntax and that means no ramp up time to learn yet another JS framework. However, since the goal for Zepto is to support only modern Webkit browsers, few things that jQuery used to offer are now lost conveniences but this is still not a problem. You can check the jQuery source and for the most part copy it over into your Zepto source and be done with it otherwise you might have to Zepto-ize (lame attempt for Zepto lingo, sorry!) it.

To help with porting I read this useful article. It even has a performance comparison at the end of the article. Choosing a javascript framework is absolutely optional. You only use one when you need to add extensions like a date picker that looks like iOS or if you want to use some really good javascript template engine…etc. You still have the option of writing good old regular javascript with document.getElementById, document.getElementByClassName(with HTML5)…you get the point.

Another great point to consider while developing for iOS and Android using HTML5 is making use of translate3d and using CSS3 media queries to make the icons, images look sharper on a retina display. Watch this video of how translate3d helps give your app that native feel to it. Hardware acceleration baby!