Skip to content

Introduction to Vue

Or Abramovich edited this page Nov 19, 2017 · 2 revisions

Intro

Vue is a progressive framework for building UI. It is component oriented and uses templates in order to create and view layer of the application. Vue, like other frameworks (like Angular) adds more power to the HTML and allows us to write more declarative code which is generated, by Vue, to a valid HTML code that browsers understand.

Comparing to other frameworks - Why Vue?

Here I will refer only to the differences that are more likely to be relevant to our needs, for a fuller comparison click here.

AngularJS

  • Easy to learn: AngularJS is harder to learn and considered more complex. Learning Vue for our needs takes less time,
  • Flexibility: AngularJS is stricter. It makes our app be structured in a specific way. Vue is more flexible, which may sound like a thing that might lead to a messy project. In order to prevent such a situation we can use Webpack and write out components in a structured way and still have the benefits in Vue flexibility.
  • Performance: Vue has better performance because of the way it implements its watches. They are asynchronous and there is no need in re-evaluating all of them anytime something changes.

React

  • Templates vs JSX: React uses JSX, which is a way to write HTML in the Javascript, and use Javscript to manipulate it - which is a powerful tool. Vue also supports using JSX, but also offers the templates alternative. We can take any valid HTML code and use it as our template right away. Moreover, I find writing HTML templates cleaner.
  • Scoped Style: This concept means creating a styling for each component and not worrying about different style definitions from other components that might break our definitions. Vue (with Webpack) gives a very easy platform to use this concept - with the known HTML style elements.
  • Mobile: React has React Native which allows us to write mobile applications using the same component model. Vue also has it, using Weex we can take our vue-components and write with them an app.

Angular

I won't get into details here because I believe that Angular is irrelevant in our case - it is too heavy and hard to learn for our case.

Writing a Small Appication

I believe that the best way to learn something is by using examples. Here I will build a simple application which displays a list of apartments and allows removing and deleting apartments from the list.

Using Webpack

Using this tool is not obligatory, but using it allows us to write our components in a more organized way.

Webpack is a bundling tool. It get as an input a Javascript file in our case, and then goes after all its dependencies, "compiles" them and outputs a single bundle - a single script file. We can think about it like compiling many C files into one executable file. Vue provides vue-loader for Webpack. This extension to Webpack allows us to write single-file-components, which are eventually "compiled" into a valid Javascript code that browsers can execute.

In order to use this, we will use NPM. We can go to https://nodejs.org, download and install it and now we have Node Package Manager which will be used to installing and running Webpack.

After installation finishes, we will navigate to the path where we want to open a directory for our project. Then we will open our CLI and run the following: npm install -g vue-cli vue init webpack-simple roomates cd roomates npm install npm run dev

Our default browser should open at this point and display a page with Vue logo.

Understanding what's going on

For this tutorial, we will look at the index.html file and it the src folder. index.html file is our base file, this file contains a single element with "app" id. In the src folder we have main.js:

import Vue from 'vue'
import App from './App.vue'

new Vue({
  el: '#app',
  render: h => h(App)
})

Here we import Vue and App component. Then we create a new Vue instance and inform Vue that the element with the "app" id is our application element. Vue will now replace this element with our App component.

Now we will go and explore src/App.vue which contains our application:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
      <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
      <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
    </ul>
  </div>
</template>

In the template tag we will write our template. This is HTML code that has some additional features added by Vue. we will learn about them later.

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

Here we export our component. The data function returns an object which contains the data that will be injected to our template.

<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;
}

h1, h2 {
  font-weight: normal;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

These are standard CSS rules. We can change <style> to <style scoped>` to get scoped styling.

Starting to Code

Firstly we will delete the template and style tags contents. We want our app to contain a text field, which adds an apartment to a displayed list of apartments when we hit enter, For our example, each list item will also be a component.

ListItem component

In the src folder we will create a new components folder. In this folder we will create a ListItem.vue file:

<template>
    <li>
        {{ text }}
        <button @click="removeMe">x</button>
    </li>
</template>

Our template is a simple list item HTML element with some Vue options. {{ text }} means "write here the value of the text variable". @click means "onclick", when clicking we invoke the removeMe method.

<script>
    export default {
        name: 'list-item',
        props: ['itemIndex', 'itemText'],
        data: function() {
            return {
                text: this.itemText,
                index: this.itemIndex
            }
        },
        methods: {
            removeMe: function() {
                this.$emit('remove', this.index);
            }
        }
    }
</script>

Here we export our component.

  • The props element is an array that defines variables parameters the parent component can pass.
  • data is a function return a object that contains the variables of the component (such as text).
  • methods is an object that contains the methods defined in this component.

So, we receive the index and the text of this list element. We display the text of the item and a button for removing it. When the button is clicked we run removeMe. $emit is a function that triggers an event. The parent will listen to this event and will handle it. Here we trigger an event named "remove" (we can use any name we want) and pass our index as a parameter.

Using our component

Now we will open src/App.vue:

<template>
    <div>
        <input type="text" @keyup.enter="addItem" />
        <ul>
            <li
                    is="list-item"
                    v-for="(apartment, index) in apartments"
                    :item-index="index"
                    :item-text="apartment"
                    @remove="removeItem"
            ></li>
        </ul>
    </div>
</template>

We define here an input element and a list. We declare that when a keybourd key up event is triggered and the key pressed is enter we invoke addItem. Also we define a list. Each list item is a ListItem component according to the is attribute. Generally we would use a <list-item> tag instead of the is attribute. Here we must use li tag because we are in a ul so we use the is attribute.

  • v-for="(apartment, index) in apartments" means that we iterate over the apartment variable and for each iteration we display another list item, where apartment is the current element and index is its index.
  • :item-index="index" means we pass the index (the colon at the beginning replaces the v-bind and indicates that index is a variable and not a string literal) to the item-index prop of the list-item component.
  • :item-text="apartment" same. We pass the apartment variable to the item-text prop.
  • @remove="removeItem" - when remove event triggers we invoke the removeItem method.
<script>
    import ListItem from './components/ListItem.vue'

    export default {
        name: 'app',
        components: {
            ListItem
        },
        data () {
            return {
                apartments: ['ex1', 'ex2', 'ex3']
            }
        },
        methods: {
            removeItem: function(index) {
                this.apartments.splice(index, 1);
            },
            addItem: function(e) {
                this.apartments.push(e.target.value);
            }
        }
    }
</script>

Here we import our component and name it as ListItem. We register it in the components field. At the beginning we have 3 example apartments in the list.

  • removeItem goes to the apartment array and just removes the element in the specified index. The beauty here is the fact that mutating the array will automatically change the UI, Vue does that for us.
  • addItem just adds a new item to the array, and again the list is updated automatically.

That's it! We can now remove and add items to our list. We built a small application with components and used Webpack. There are many more options that Vue offers, you can read more here.

Clone this wiki locally