Book Image

Vue.js 2 Cookbook

By : Andrea Passaglia
Book Image

Vue.js 2 Cookbook

By: Andrea Passaglia

Overview of this book

Vue.js is an open source JavaScript library for building modern, interactive web applications. With a rapidly growing community and a strong ecosystem, Vue.js makes developing complex single page applications a breeze. Its component-based approach, intuitive API, blazing fast core, and compact size make Vue.js a great solution to craft your next front-end application. From basic to advanced recipes, this book arms you with practical solutions to common tasks when building an application using Vue. We start off by exploring the fundamentals of Vue.js: its reactivity system, data-binding syntax, and component-based architecture through practical examples. After that, we delve into integrating Webpack and Babel to enhance your development workflow using single file components. Finally, we take an in-depth look at Vuex for state management and Vue Router to route in your single page applications, and integrate a variety of technologies ranging from Node.js to Electron, and Socket.io to Firebase and HorizonDB. This book will provide you with the best practices as determined by the Vue.js community.
Table of Contents (19 chapters)
Title Page
Credits
About the Author
About the Reviewer
www.PacktPub.com
Customer Feedback
Dedication
Preface

Upgrading to Vue.js 2


If you need to upgrade your Vue app to version 2, most of your code is good to go. There are a couple of features though that need some modifications. Some are simple renaming, some are more involved.

How to do it...

To give your migration a head start; Chris Fitz (a member of the Vue core team) created a little helper app that will scan your code and guide you in the migration:

  1. Install Vue Migration Helper with the following npm command:
        npm install -g git://github.com/vuejs/vue-migration-helper.git
  1. Navigate to your app folder.
  2. Run the program with the following command:
        vue-migration-helper

All the lines in which a change is necessary will be highlighted. Once you are finished updating, or if you still have doubts, you should take a look at the official documentation migration page at https://rc.vuejs.org/guide/migration.html.

How it works...

Reading through the documentation will help you understand the critical points that need to be updated. Here I will provide you a rationale for some of the most challenging modifications.

Deprecation of $broadcast, $dispatch, and the events option

Both methods $broadcast and $dispatch are now merged in the $emit method with the same syntax as the old version. Unfortunately, replacing every instance of $broadcast and $dispatch with $emit is not guaranteed to always work because the pattern used to manage events is a little different now.

In Vue 1, you had events follow a path either downward (for $broadcast) or upward (for $dispatch), and horizontally (for $emit) through the hierarchical tree.

To be honest, I never liked having two (three if you count the old $emit) methods for emitting events. It was confusing even in the smallest contexts because you had to ask yourself is this event for parents or children? Most of the time it was not that important of a distinction, you just wanted your method to fire. But there is no such thing as a free lunch; we have to add a moving part to our system to make everything work in the new paradigm.

Now all events should pass through one or more central hubs. The role of this central hubs can be taken by a Vue instance since they implement the necessary interface.

When emitting an event consumed by v-on, you're good to go by replacing $broadcast with $emit, since the event doesn't have to travel far. On the other hand, if you are defining an interface for a component in terms of events, you will have to say goodbye to the events option since it will not work anymore. This is the direct consequence of having all the events passing through a hub--the events option wouldn't know where to register all the events. This is the trade off for having a single emitting method: it fires in every direction but only in a precise piping.

Let's say you have a dedicated empty Vue instance that will act as an event hub:

var eventBus = new Vue()

If you are writing a teapot component and you want to register the brew event, you will write in the created hook something like the following:

new Vue({ 
  el: '#app', 
  components: { 
   comp1: { 
         template: '<div/>', 
         created () { 
         eventBus.$on('brew', () => { 
         console.log('HTTP Error 418: I'm a teapot') 
        }) 
      } 
    }, 
    comp2: { 
         template: '<div/>', 
         created () { 
         eventBus.$emit('brew') 
      } 
    } 
  } 
})

And with the HTML:

<div id="app"> 
  <comp1></comp1> 
  <comp2></comp2> 
</div>

Every time the brew event is emitted with eventBus.$emit('brew'), the console will output a message.

Note

As you can see, this example is not very scalable. You cannot register a lot of events in the created hook and then expect to easily keep track of what they do and in which hub they are registered. For these more involved scenarios, the suggested way to proceed is to use Vuex, introduced in later recipes.

Any component you'll write can act as an event hub. You also have the API methods $off which deletes listeners, and $once, which listens for an event but only once.

Deprecation of array filters

If you had a lot of filtered v-for lists, I have bad news for you. Even if in the wild the most common use for filters was with v-for, the community chose to remove this feature. The reason is mainly because having a lot of filters, often piped together, was hard to reason about and thus to maintain.

The new recommended way to filter a list is with a computed property. Luckily for you, we have an entire recipe on how to do that. See the recipe Filtering a list with a computed property in the next chapter.

Deprecation of Vue.config.delimiters

Custom delimiters are not at the component level. If you want, you can have two different components using different delimiters.

This is fairly easy to upgrade and allows you to write components intended to be used inside other template engines:

<div id="app"> 
  {!msg!} 
</div>

new Vue({ 
 el: '#app', 
 data: { 
   msg:'hello world' 
 }, 
 delimiters: ['{!','!}'] 
})

Renaming of life cycle hooks

Life cycle have now a more consistent naming that will help with remembering their names in the long run:

Old hook

New hook

init

beforeCreate

created

created

beforeCompile

created

no equivalent

beforeMount

compiled

mounted

ready

mounted

attached

no equivalent

detached

no equivalent

no equivalent

beforeUpdate

no equivalent

updated