Vue 2.5 shipped significant TypeScript improvements and a new error handling hook. Here's what changed.
Better TypeScript Support with Vue.extend
typescript
// Before 2.5: using vue-class-component decorator syntax
import Vue from "vue";
import Component from "vue-class-component";
@Component({
template: '<button @click="onClick">Click!</button>',
})
class MyComponent extends Vue {
message: string = "Hello!";
onClick() {
window.alert(this.message);
}
}
// Vue 2.5+: Vue.extend works better with TypeScript
import Vue from "vue";
const MyComponent = Vue.extend({
data() {
return {
message: "Hello!" as string,
};
},
methods: {
greet(): void {
console.log(this.message); // correctly typed
},
},
});
The type inference in Vue.extend() is significantly improved: this.message, this.$data, and this.$store all have correct types without decorators.
Functional Component Improvements
Functional components (stateless, no this) got better TypeScript support:
typescript
// Functional component with TypeScript
import { FunctionalComponentOptions } from "vue";
const FancyList: FunctionalComponentOptions = {
functional: true,
props: {
items: Array,
},
render(createElement, context) {
return createElement(
"ul",
context.props.items.map((item) => createElement("li", item.name)),
);
},
};
errorCaptured Hook
Vue 2.5 introduced errorCaptured — the Vue equivalent of React's Error Boundaries:
javascript
export default {
name: "ErrorWrapper",
data() {
return { error: null };
},
errorCaptured(err, vm, info) {
// err: the error object
// vm: the component that threw
// info: a string describing where the error was caught
this.error = err.message;
// Return false to prevent the error from propagating further
return false;
},
};
Usage:
html
<template>
<div>
<div v-if="error" class="error-display">Component error: {{ error }}</div>
<slot v-else />
</div>
</template>
The error propagates up the component tree until a component with errorCaptured returns false.
v-on Multiple Event Listeners
html
<!-- Before 2.5: repeated v-on -->
<input v-on:focus="onFocus" v-on:blur="onBlur" v-on:input="onInput" />
<!-- Vue 2.5+: v-on with object syntax -->
<input v-on="{ focus: onFocus, blur: onBlur, input: onInput }" />
This is particularly useful when building higher-order components that need to pass through all event listeners.