Comparing Vue js and Angular by building a same application in both the frameworks

Lets build a simple Conference application in Vue.js and Angular. It will basically have following sections :

  1. It will list down all the speakers speaking in the conference
  2. For each session you can rate it out of 5
  3. You can delete the session
  4. You can do multi select and delete multiple sessions at one time
  5. You can also add a new session
  6. You can show/hide some sections
  7. You can attach different CSS to each speaker section

This is how the application will look like :

Step 1 : Basic structure

Vue js

This is how basic HTML will look like at the start :

<html>   <head>      <script src="https://cdn.jsdelivr.net/npm/vue"></script>          </head>   <body>      <!--The content below is only a placeholder and can be replaced.-->          <div id="app">      </div>    <script src="index.js"></script></body></html>

Here is the starting javascript code which will load Vue js

let app = new Vue({  el: '#app'})

This basically tells Vue that DIV element with the ID ‘app’ is the place where whole one page application needs to be loaded

Angular

This is how HTML will look like at the start :

<!doctype html><html lang="en"><head>  <meta charset="utf-8">  <title>AngularDemo</title></head><body>  <app-root></app-root></body></html>

Here is starting JS file :

import { Component } from '@angular/core';
@Component({  selector: 'app-root',  templateUrl: './app.component.html',  styleUrls: ['./app.component.css']})export class AppComponent {}

We need to import angular components. Then we tell angular the selector present in the HTML file in which it needs to insert the generated HTML. templateUrl will be URL to file which will contain the HTML structure of the page. styleUrls will contain the path to CSS files

We have also created a new class AppComponent which is empty currently

Step 2 : Listing the speakers

Vue js

First we need to define variables in JS side which can be accessed from the HTML page. All these variables need to be declared under ‘data’ property

let app = new Vue({  el: '#app',  data: {  }})

Lets add ‘sessions’ variable which will contain details of all the sessions like speaker, topic, time , image of speaker.

let app = new Vue({  el: '#app',  data: {     sessions: [      { id: 100, speaker: 'Uday Ogra', time : '10:00 AM', topic: 'Integrating modern day Javascript framewroks with ColdFusion', img: 'https://pbs.twimg.com/profile_images/1518734182/uday2_400x400.jpg' },      {        id: 101, speaker: 'Suchika Singh', time : '11:00 AM',topic: 'All about scheduled tasks and using them in ColdFusion', img: 'https://www.adobe.com/content/dam/acom/en/devnet/authors/bio/s/Suchika_Singh.jpg'      },{        id: 102, speaker: 'Pavan Kumar', time : '01:00 PM',topic: 'Securing your CF applications and using security analyzer tool', img: 'https://www.adobe.com/content/dam/acom/en/devnet/authors/bio/i/Immanuel_noel.jpg'      },{        id: 103, speaker: 'Raj Pandian', time : '02:00 PM',topic: 'Scaling up your CF applications by using distributed caching', img: 'https://www.adobe.com/content/dam/acom/en/devnet/authors/bio/i/Immanuel_noel.jpg'      },,{        id: 104, speaker: 'Pavan Kumar', time : '02:30 PM',topic: 'Scaling up your CF applications by using distributed caching', img: 'https://www.adobe.com/content/dam/acom/en/devnet/authors/bio/i/Immanuel_noel.jpg'      }    ]

Now on the HTML side we need to iterate over these sessions and display them. Here is the code for that :

<div v-for='session in sessions'>
	<img class='speakerImg' v-bind:src='session.img' />
	<div class='speakerName'><i>{{session.speaker}}</i></div>
	<div class='topic'>{{session.topic}}</div><br>
	<div class='time'><i>@{{session.time}}</i></div><br>
</div>

Here we use ‘v-for’ directive for iterating over the ‘sessions’ variable which we had just defined at the JS side.

Angular

Similar to Vue js lets store all sessions related information in the sessions variable inside AppComponent class which we had created earlier

export class AppComponent {  sessions = [    { id: 100, speaker: 'Uday Ogra', time: '10:00 AM', topic: 'Integrating modern day Javascript framewroks with ColdFusion', img: 'https://pbs.twimg.com/profile_images/1518734182/uday2_400x400.jpg' },    {      id: 101, speaker: 'Suchika Singh', time: '11:00 AM', topic: 'All about scheduled tasks and using them in ColdFusion', img: 'https://www.adobe.com/content/dam/acom/en/devnet/authors/bio/s/Suchika_Singh.jpg'    }, {      id: 102, speaker: 'Pavan Kumar', time: '01:00 PM', topic: 'Securing your CF applications and using security analyzer tool', img: 'https://www.adobe.com/content/dam/acom/en/devnet/authors/bio/i/Immanuel_noel.jpg'    }]

Now on the HTML side we need to iterate over these sessions and display them. Here is the code for that :

<div  *ngFor="let session of sessions">                <img class='speakerImg' src='{{session.img}}' />                <div class='speakerName'><i>{{session.speaker}}</i></div>
        <div class='topic'>{{session.topic}}</div><br>
        <div class='time'><i>@{{session.time}}</i></div><br></div>

So we use *ngFor to iterate over sessions variable and then use double curly braces( {{ }}) to access the properties

Step 3: Rating the session

Vue js

You will have the option to rate the session out of five. In the HTML side we need to add the SELECT section and RATE button

<select v-model='currentRatings[session.id]'>   <option v-for='r in ratings' v-bind:value='r.value' >		{{r.text}}   </option></select>
<button type="submit" value='Rate'						v-on:click="rateSession(session.id,currentRatings[session.id])">Rate</button>

At the Javascript side we have defined ‘ratings’ variable :

ratings: [{value :1, text : '1 star'},{value :2, text : '2 star'},{value :3, text : '3 star'},{value :4, text : '4 star'},{value :5, text : '5 star'} ],

In the HTML code we iterate over ratings and construct our select component.

We have also defined ‘ currentRatings’ variable which will contain the rating for each session

currentRatings: {}

Next is rate button which will invoke the function on JS side which will store the rating.

let app = new Vue({  el: '#app',  data : {},methods: {   rateSession: function (id, rating) {      app.$set(app.ratingMap, id, rating);    }})

We were using DATA property to define various variables. To define functions we need to declare them inside METHODS property.

Here rateSession method is just updating the map which contains session ID vs its rating.

Angular

Similar to Vue js we will construct SELECT component and RATE button

<select [(ngModel)]='currentRatings[session.id]' class='dropDown'>          <option *ngFor='let r of ratings' value="{{r.value}}">            {{r.text}}          </option>
        </select>
        <button type="submit" class="btn btn-secondary" value='Rate'          (click)="rateSession(session.id,currentRatings[session.id])">Rate</button>

At the model side we have defined ‘ratings’ variable :

ratings: [{value :1, text : '1 star'},{value :2, text : '2 star'},{value :3, text : '3 star'},{value :4, text : '4 star'},{value :5, text : '5 star'} ],

In the HTML code we iterate over ratings and construct our select component.

Like bue js we have also defined ‘ currentRatings’ variable which will contain the rating for each session

currentRatings: {}

Next is rate button which will invoke the function on JS side which will store the rating.

rateSession = function (id, rating) {    this.ratingMap[id] = rating;  }

Here rateSession method is just updating the map(ratingMap) which contains session ID vs its rating.

Step 3: Deleting a session

Vue js

Let’s add the functionality to delete a session from the pre-defined sessions list. We will attach v-on:click event to Delete button

<button type="submit" class="btn btn-danger" v-on:click="deleteSession(session.id)">Delete</button>

Here is the deleteSession method which removes the session from the sessions data structure.

deleteSession: function (id) {      var filtered = this.sessions.filter(function (value, index, arr) {
        return value.id != id;
      });
      this.sessions = filtered;
    }

Angular

In Angular we will attach (click) event to Delete button

<button type="submit" class="btn btn-danger" (click)="deleteSession(session.id)">Delete</button>

Here is the deleteSession method which removes the session from the sessions data structure. Its exactly same as Vue js

deleteSession = function (id) {    var filtered = this.sessions.filter(function (value, index, arr) {      return value.id != id;    });    this.sessions = filtered;  }

Step 4: Deleting multiple sessions

Vue js

If we wanted to delete multiple sessions, clicking delete on each sessions would be a bit tiring. So lets add a feature using which we can delete multiple sessions with single click. So we will add a checkbox to each session. It will be mapped to checkedSessions model. We have kept session’s ID as ID of these checkboxes. checkedSessions model will contain an array of all session ids which user has checked

<input type="checkbox" v-bind:id="session.id" v-bind:value="session.id" v-model="checkedSessions">

Here is the button which will do multi delete. It will be visible only if user has clicked atleast one check box.

<button v-if='checkedSessions.length > 0' type="submit" class="btn btn-danger" v-on:click="deleteMultiSessions">Delete Slected Sessions</button>

Here is deleteMultiSessions method which will internally make calls to deleteSession method

deleteMultiSessions: function () {      for(var idx in this.checkedSessions){         this.deleteSession(this.checkedSessions[idx] );      }    }

Angular

In Angular multi checkbox functionality will be handled in a different way. Here also lets add a checkbox to each session. It will be mapped to checked attribute of each session.

<input type="checkbox" name='{{session.id}}' id="{{session.id}}" value="{{session.id}}"          [(ngModel)]="session.checked">

Here is the button which will do multi delete. It will be visible only if user has clicked atleast one check box.

<button *ngIf='isAnySessionChecked()' type="submit" class="btn btn-danger" (click)="deleteMultiSessions()">Delete      Slected Sessions</button>

Here we are calling isAnySessionChecked method to check if atleast one session is checked. *ngIf is equivalent of if construct of any language.

isAnySessionChecked = function () {    for (var session in this.sessions) {      var session = this.sessions[session];      if (session.checked) {        return true;      }    }

Here is deleteMultiSessions method :

deleteMultiSessions = function () {    var filtered = this.sessions.filter(function (value, index, arr) {      return !value.checked;    });    this.sessions = filtered;  }

So unlike Vue js this operation was a bit more complex in Angular.

Step 5 : Adding a new session

Vue js

We had a pre-defined list of sessions. But now we want to have the ability to add a new session also. So we created a form with fields like speaker’s name, session’s topic and time. For each field we have defined a model (v-model) which will exist on the JS side. Whatever value a user enters in these fields, the corresponding models will get those values.

<h1>Add new Session</h1>			<form >				<div class="form-group row">					<label class="col-sm-2 col-form-label">Enter Speaker's Name</label>					<div class="col-sm-8">						<input class="form-control" v-model='speaker' />					</div>				</div>				<div class="form-group row">						<label class="col-sm-2 col-form-label">Enter Topic</label>						<div class="col-sm-8">							<textarea v-model='topic' class="form-control" v-on:keyup.enter="addSession()"></textarea>						</div>				</div>				<div class="form-group row">						<label class="col-sm-2 col-form-label">Enter Time</label>						<div class="col-sm-3">							<input v-model='time' class="form-control" v-on:keyup.enter="addSession()" />						</div>				</div>					<button type="button" class="btn btn-secondary" v-on:click="addSession()">Add Session</button>			</form>

We also attached addSession method with onClick event of time input by using v-on:click

In the addSession method we just push one more entry to the already existing sessions data structure

addSession: function () {      this.sessions.push({ id: this.sessions.length + 1, speaker: this.speaker, topic: this.topic, time : this.time });      this.showAdvancedSettings = false; // we will talk about this later    }

Angular

Like Vue js for each field we have defined a model (ngModel) which will exist on the JS side. Whatever value a user enters in these fields, the corresponding models will get those values.

<h1>Add new Session</h1>    <form>      <div class="form-group row">        <label class="col-sm-2 col-form-label">Enter Speaker's Name</label>        <div class="col-sm-8">          <input class="form-control" [(ngModel)]='speaker' name='first' />{{speaker}}        </div>      </div>      <div class="form-group row">        <label class="col-sm-2 col-form-label">Enter Topic</label>        <div class="col-sm-8">          <textarea [(ngModel)]='topic' name='second' class="form-control" ></textarea>        </div>      </div>      <div class="form-group row">        <label class="col-sm-2 col-form-label">Enter Time</label>        <div class="col-sm-3">          <input [(ngModel)]='time' name='third' class="form-control"  />        </div>      </div>      <button type="button" class="btn btn-secondary" (click)="addSession()">Add Session</button>    </form>

In the addSession method we just push one more entry to the already existing sessions data structure

addSession = function () {    this.sessions.push({ id: this.sessions.length + 1, speaker: this.speaker, topic: this.topic, time: this.time });    this.showAdvancedSettings = false;// will discuss later  }

Step 6 : Show/Hide section

Vue js

Adding new session is something which might not be used many times. So I wanted to hide this section and show it only once user wanted to add a new session

So we have added another variable with the name 
showAdvancedSettings whose default value would be false. We have a button, clicking on whom will toggle the value of 
showAdvancedSettings

<button type="submit" v-on:click="showAdvancedSettings = !showAdvancedSettings">Show/Hide Advanced Settings</button>

Now we have added v-if directive to the ‘Add new session’ section. If 
showAdvancedSettings is true, only then this section will be shown

<div v-if='showAdvancedSettings'>  <h1>Add new Session</h1></div>

In the addSession method we make showAdvancedSettings as false so that this section gets hidden once a new session has been added.

Angular

In Angular also we have defined a variable showAdvancedSettings whose default value would be false. We have a button, clicking on whom will toggle the value of showAdvancedSettings

<button type="submit" class="btn btn-secondary" (click)="showAdvancedSettings = !showAdvancedSettings">Show/Hide      Advanced Settings</button>

Now we have added *ngIf directive to the ‘Add new session’ section. If 
showAdvancedSettings is true, only then this section will be shown

<div v-if='showAdvancedSettings'>  <h1>Add new Session</h1></div>

Like Vue js, in the addSession method we make showAdvancedSettings as false so that this section gets hidden once a new session has been added.

Step 7 : Different CSS for different speakers

Vue js

While displaying the speaker info I wanted to have different background color for alternating speakers. But as we were inside a for loop while displaying each speaker, how can we assign different CSS for alternating speakers? Well, that is quite easy in Vue.js. We can make use of directive ‘v-bind:class’ and inside that define the expression whose evaluated value will decide which CSS class to apply for that particular component.

<div v-bind:class="{ even: index%2 == 0  , odd : index%2 ==1}"	v-for='(session, index) in sessions'></div>

So for even numbered speakers we are applying ‘even’ CSS class and for odd numbered speakers we are applying ‘odd

There is slight change in v-for syntax also. As we needed the index of the loop to decide the CSS we used (session,index) iterator instead of just (session).

Angular

In Angular we can make use of directive [ngClass] and inside that define the expression whose evaluated value will decide which CSS class to apply for that particular component.

<div class='col-md-3 offset-top-1' *ngFor="let session of sessions; let i = index"      [ngClass]="{'even' : i%2 == 0, 'odd' : i%2 == 1}"></div>

So for even numbered speakers we are applying ‘even’ CSS class and for odd numbered speakers we are applying ‘odd

There is slight change in *ngFor syntax also. As we needed the index of the loop to decide the CSS, we used (let i = index) statement to have an access to index

 — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

So this pretty much brings us to the end of this tutorial. We have seen most of the code is pretty much the same. These two frameworks are very similar to each other in terms of coding. Reactjs is totally different from both of these and soon I will come up with another article comparing these 3 frameworks.

You can find the code for Vue js app here : https://github.com/udayogra/vuebasic

Angular app can be found here : https://github.com/udayogra/angularbasic

Uday Ogra

Connect with me at http://facebook.com/tendulkarogra and lets have some healthy discussion :)

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *