Upgrading to Vue.js 2.2

Joshua Bemenderfer

Vue 2.2 was just released with a plethora of neat changes. Here’s a guide to what changed and how it might affect your app, along with migration patterns in the case you relied on something that changed. Vue 2.2 does not introduce any breaking changes to the public API surface, but it does make some significant internal changes that might affect your app if it relies on them.

New Features

Vue 2.2 provides an interesting set of new features that are rather minor, but should streamline your development experience.

v-model customization

Previously, v-model passed input directly to :value and took input from @input (or @change if using v-model.lazy.) While that is still the default behavior, you can now customize the property and event used for v-model with the model component configuration property.

ChildComponent.vue

model: {
  prop: 'myCustomProp',
  event: 'myCustomEvent'
}

This makes v-model use :myCustomProp and @myCustomEvent instead of :value and @input:

ParentComponent.vue

<!-- v-model version -->
<child-component v-model="binding"></child-component>
<!-- Translates to: -->
<child-component :myCustomProp="binding" @myCustomEvent="evt => { binding = evt }"></child-component>

Provide / Inject

Vue now provides a basic dependency injection mechanism, comparable to React’s context system. It allows you to mount properties to a parent component, and have them accessible for injection in all of its descendants.

This is great for having easily-accessible services for certain sections of your app, or sharing data transports.

Note: Injected properties are not reactive. However, reactive objects can be passed through the injection system.

ParentComponent.vue

<template>
  <child-component-1>
    <child-component-2>
      <child-component-3></child-component-3>
    </child-component-2>
  </child-component-1>
</template>

<script>
import {ChildComponent1, ChildComponent2, ChildComponent3} from './components'

const ThingIWantToShare = {
  importantString: 'boop'
}

export default {
  provide: {
    ThingIWantToShare
  }
}
</script>

Now any component that is a child of ParentComponent can inject the ThingIWantToShare property.

components/ChildComponent3.vue

<template>
  <p>{{ ThingIWantToShare.importantString }}</p>
</template>

<script>
export default {
  inject: ['ThingIWantToShare']
}
</script>

Server-side rendering

Server-side Rendering has seen some improvements to support a direct template option, as well as a modified bundle format allowing you to handle sourcemaps and code splitting much better.

This is a tricky topic, and the documentation is still in flux. Watch this space for more details.

Changes

There are a number of minor changes as well that refine the development experience with Vue further.

Templates

  • transition and transition-group tags now allow you to define the durations for the transition, like so.
<transition :duration="durationInMs"></transition>
<transition :duration="{enter: durationInMs, leave: durationInMs}"></transition>
  • v-for now requires that you specify a key attribute when using it on a component. This will not affect your app, but will log warnings in the console. This is to prevent common DOM-diffing issues that stem from dealing with reactive objects without knowing which component is tied to what key. This was already best practice, and adding the key to your existing apps would be a good idea.
  • v-on:click (@click) now supports the .left, .middle, and .right mouse button modifiers for convenience, allowing you to have separate handlers for each mouse button.
  • The template parser now throws an error if it encounters an unclosed tag. (<section><element></section> is no longer valid.) Instead, if you intend to have an unclosed tag, use a self closing tag (<element/>) instead, or just close the tag manually.
  • Any components that are descendants of a keep-alive component, no matter how nested, will now have their activated and deactivated lifecycle events fired.

Error Handling

There are some significant changes to how Error Handling works in Vue 2.2 in order to avoid crashes if a component fails to initialize, Vue now sends errors in lifecycle hooks to a global error handler. This means you no longer have to use try / catch inside of your lifecycle hooks.

If you wish to deal with these errors explicitly, you can use a renderError(h, error) render function which is separate from your normal template or render function to handle displaying them.

Additionally, the errorHandler configuration option, Vue.config.errorHandler(err, component, errorType), now allows you to hook into all render errors in your app and handle them. If you do not define a function here, the thrown errors will not crash the app, but instead log the error with console.error.

Other

Other minor changes include:

  • The current properties of a component are exposed via this.$props.
  • If your browser supports the console.trace() API, you can turn on Vue.config.performance in development mode to get performance details in the devtools timeline.
  • this.$on(String | Array<String>, function) now accepts an array of event names to allow you to register the same handler for multiple events. this.$off does not yet support removing a handler from an array of events.
  • Vue.delete(Object | Array, String | Number) now supports deleting an item at an index in an array.

Troubleshooting / Migration

  • If you previously relied on Vue.util for anything, it’s possible that your code no longer functions. Many properties and methods have been removed from it, and it should not be used outside of Vue core.
  • Because of a change in the way props and computed props are defined internally, if you performed any calls to Object.hasOwnProperty to validate properties and computed properties, it will no longer function as expected. On the bright side, the change should greatly improve speed and memory overhead in some cases.
  • In Webpack 2, const Vue = require(‘vue’) no longer works, you should use import Vue from ‘vue’ instead, or const Vue = require(‘vue’).default, if you absolutely cannot use ES Module syntax.
  • If your build chain does not appear to be working properly, make sure you upgraded vue-template-compiler and vue-loader / vueify along with vue.

That concludes the changes for Vue 2.2. As the documentation for the new features is expanded, we’ll try to keep this post up-to-date. Enjoy!

  Tweet It
✖ Clear

🕵 Search Results

🔎 Searching...