Book Image

Front-End Development Projects with Vue.js

By : Raymond Camden, Hugo Di Francesco, Clifford Gurney, Philip Kirkbride, Maya Shavin
Book Image

Front-End Development Projects with Vue.js

By: Raymond Camden, Hugo Di Francesco, Clifford Gurney, Philip Kirkbride, Maya Shavin

Overview of this book

Are you looking to use Vue 2 for web applications, but don't know where to begin? Front-End Development Projects with Vue.js will help build your development toolkit and get ready to tackle real-world web projects. You'll get to grips with the core concepts of this JavaScript framework with practical examples and activities. Through the use-cases in this book, you'll discover how to handle data in Vue components, define communication interfaces between components, and handle static and dynamic routing to control application flow. You'll get to grips with Vue CLI and Vue DevTools, and learn how to handle transition and animation effects to create an engaging user experience. In chapters on testing and deploying to the web, you'll gain the skills to start working like an experienced Vue developer and build professional apps that can be used by other people. You'll work on realistic projects that are presented as bitesize exercises and activities, allowing you to challenge yourself in an enjoyable and attainable way. These mini projects include a chat interface, a shopping cart and price calculator, a to-do app, and a profile card generator for storing contact details. By the end of this book, you'll have the confidence to handle any web development project and tackle real-world front-end development problems.
Table of Contents (16 chapters)
Preface

Vue Directives

Vue's templating language allows you to interpolate the HTML code with JavaScript expressions and Vue directives. This templating pattern is often referred to as syntax sugar because it does not change how the code itself works, just how you use it. Syntax sugar allows you to clearly define template-specific logic inside of your HTML without the need to abstract this logic elsewhere in your project or return copious amounts of HTML directly from your JavaScript code. All Vue based directives are prefixed with v-*, which indicates that it is a Vue specific attribute:

  • v-text: The v-text directive has the same reactivity interpolation does, except you reference the same piece of data inside of a directive. Interpolation (curly braces) {{ }} is more performant than the v-text directive; however, you may find yourself in situations where you have pre-rendered text from a server and want to override it once your Vue application has loaded. For example, you can predefine static placeholder text while the DOM waits for the data and v-text attributes to eventually replace it.
  • v-once: As a directive, this is unique in that you pair it with other directives to augment how they function. Passing data via v-text or interpolated curly braces into the HTML element this attribute is added to will stop the Vue instance from reloading the element with new data, removing the reactivity of the element. This is handy for situations where you want to render decorative elements using data, but do not want them to update when the data changes after the initial render.
  • v-html: This directive will render valid HTML in your data string inside of the HTML element it has been bound to. This directive is a heavier operation than the other directives, so limited usage is recommended when other options are not otherwise available.

    Note

    <script> tags can be run in this directive. Only render content originating from secure or trusted sources.

  • v-bind: This directive is one of the most widely used directives in Vue. Throughout Vue, you will be binding reactive data to HTML attributes and passing data into props using this directive's :attr shortcut instead of v-bind:attr.
  • v-if: To control the display state of HTML elements inside the template, you will often use v-if to completely remove elements from the DOM tree. So far, you have seen how to interpolate conditionals like this {{ isTrue ? 'Show this': 'Not this' }}. With the v-if directive, you can control entire blocks of HTML syntax. v-else-if can be used like else if statements and finish with v-else, which is the equivalent to the catch { ... } declaration of an else { ... } statement in traditional JavaScript.
  • v-show: You can control the visible state of HTML elements by using v-show, which, instead of removing the element from the DOM tree, will apply a display: none style. The difference between a v-if and v-show is that v-show will remain as a block element in the DOM tree but will be hidden with css instead of being removed from the DOM tree. You also cannot chain v-show with v-else or v-else-if.
  • v-for: Apply this to an element you want to repeat or iterate on. This directive requires an additional prop called :key to allow it to properly reactively render; it can be as simple as a unique number.

    Consider an example where we iterate over the list element five times. Each list item will render its count (1, 2… 5):

    <ul><!-- do not apply v-for to this <ul> element -->
        <li v-for="n in 5" :key="n">{{ n }}</li>
    </ul>

Now let's look at how some of the basic directives work.

Exercise 1.06: Basic Directives (v-text, v-once, v-html, v-bind, v-if, v-show)

More complicated components will use multiple directives to achieve the desired outcome. In this exercise, we will construct a component that uses several directives to bind, manipulate, and output data to a template view.

To access the code files for this exercise, refer to https://packt.live/3fdCNqa.

  1. Open a command-line terminal, navigate into the Exercise1.06 folder, and run the following commands in order:
    > cd Exercise1.06/
    > code .
    > yarn
    > yarn serve

    Go to https://localhost:8080.

  2. Compose the following syntax inside of Exercise1-06.vue. This uses the interpolation method that we have used in previous exercises and that will be very familiar by this point:
    <template>
      <div>
        <h1>{{ text }}</h1>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          // v-text
          text: 'Directive text',
        }
      },
    }
    </script>
    <style lang="scss" scoped>
    h2 {
      margin: 40px 0 0;
      font-weight: normal;
    }
    </style>
  3. Replace the interpolation with the v-text attribute. You will notice the output will not change:
    <template>
      <div>
        <h1 v-text="text">Loading...</h1>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          // v-text
          text: 'Directive text',
        }
      },
    }
    </script>

    Figure 1.17 displays the output of the preceding code:

    Figure 1.17: The v-text directive output works very similarly to the interpolation method

    Figure 1.17: The v-text directive output works very similarly to the interpolation method

  4. Add the v-once directive on the same element. This will force this DOM element to only load the v-text data once for as long as it exists in the page:
    <template>
      <div>
        <h1 v-once v-text="text">Loading...</h1>
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          // v-text
          text: 'Directive text',
        }
      },
    }
    </script>
    ...
  5. Underneath the h1 element, include a new h2 element, which uses the v-html attribute. Add a new data key called html, which contains a string with HTML formatting in it like the following:
    <template>
      <div>
        <h1 v-once v-text="text">Loading...</h1>
        <h2 v-html="html" />
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          // v-text
          text: 'Directive text',
          // v-html
          html: 'Stylise</br>HTML in<br/><b>your data</b>',
        }
      },
    }
    </script>
    ...

    Running the preceding code will generate an output as follows:

    Figure 1.18: Output on rendering the HTML elements

    Figure 1.18: Output on rendering the HTML elements

  6. Add a new link object to the data object that contains a bunch of information such as URL, target, title, and tab index. Inside the template, add a new anchor HTML element and bind the link data object to the HTML element using the colon syntax, for example, :href="link.url":
    <template>
      <div>
        <h1 v-once v-text="text">Loading...</h1>
        <h2 v-html="html" />
      </div>
    </template>
    <script>
    export default {
      data() {
        return {
          // v-text
          text: 'Directive text',
          // v-html
          html: 'Stylise</br>HTML in<br/><b>your data</b>',
        }
      },
    }
    </script>
    ...

    The following screenshot displays the output:

    Figure 1.19: Output on binding the reactive data from 
the Vue instance to any HTML attribute

    Figure 1.19: Output on binding the reactive data from the Vue instance to any HTML attribute

  7. Apply v-if="false" to the h1 element, v-else-if="false" to h2, and v-else to the a tag like this:
    <template>
      <div>
        <h1 v-if="false" v-once v-text="text">Loading...</h1>
        <h2 v-else-if="false" v-html="html" />
        <a
          v-else
          :href="link.url"
          :target="link.target"
          :tabindex="link.tabindex"
          v-text="link.title"
        />
      </div>
    </template>

    You should only see the <a> tag in the page since we have set the conditional statements to false.

    The v-else condition will display as follows:

    Figure 1.20: False v-if statements hiding the whole HTML element from the DOM

    Figure 1.20: False v-if statements hiding the whole HTML element from the DOM

  8. Change the template to use v-show instead of the v-if statements:
    <template>
      <div>
        <h1 v-show="true" v-once v-text="text">Loading...</h1>
        <h2 v-show="false" v-html="html" />
        <a
          :href="link.url"
          :target="link.target"
          :tabindex="link.tabindex"
          v-text="link.title"
        />
      </div>
    </template>

    The output of the preceding code will be as follows:

    Figure 1.21: Changing v-show to true will display the element

Figure 1.21: Changing v-show to true will display the element

When you open the Elements tab of your browser dev tools, you should be able to observe the h2 display state set to none, as follows:

Figure 1.22: h2 displaying "display: none" for false condition

Figure 1.22: h2 displaying "display: none" for false condition

If v-show results in a true Boolean, it will leave the DOM element as is. If it resolves as false, it will apply display: none styling to the element.

In this exercise, we learned about the core Vue directives to control, bind, show, and hide HTML template elements without requiring any JavaScript outside of adding new data objects to your local state.

In the next section, we will learn how to achieve a two-way binding with the help of Vue's v-model.