概念
Vue2 默认使用的是对象选项的形式写组件,如果想使用 class 风格语法来写 Vue 组件就需要使用 Vue Class Component。
借助 @Component 装饰器可以书写一个 class 风格的 Vue 组件。可以使用类的实例属性初始化 data。注意,如果数据初始化为 undefined,则该数据将失去响应性,为了解决这个问题,可以将数据初始化为 null 或者放进 data hook 里面。另外,可以使用类的方法表示组件的 methods,render 和生命周期钩子。可以使用属性存取器定义 computed 属性。其他选项可以放到方法的装饰器里面。
基础用法
如下面代码所示,可以使用 @Component 装饰器和 extends Vue 来书写一个 class 风格的组件。定义数据 message 的初始值为 null,定义方法 changeMessage,点击 change 按钮的时候就会触发 changeMessage 事件,这个时候页面上的 message 就会自动更新为新值。此外,class 里面还可以使用生命周期函数 mounted,它会在组件挂载完后打印里面的内容。另外,可以实现一个可读可写的 computed,v-model 里面的值发生包含后,就会触发 set name,将结果保存到 firstName 和 lastName,显示值的时候又会触发 get name,返回 firstName 和 lastName 的拼凑结果。
<template>
<div>
<div>{{ message }}</div>
<button @click="changeMessage">change</button>
<input v-model="name" />
</div>
</template>
<script>
import Vue from "vue";
import Component from "vue-class-component";
@Component
export default class AppComponent extends Vue {
message = null;
firstName = "John";
lastName = "Doe";
mounted() {
console.log("hello mounted");
}
changeMessage() {
this.message = "wow";
}
set name(value) {
const splited = value.split(" ");
this.firstName = splited[0];
this.lastName = splited[1] || "";
}
get name() {
return this.firstName + " " + this.lastName;
}
}
</script>
额外的钩子
如果需要使用 Vue 插件,可以借助提供的 Component.registerHooks 方法来注册插件提供的钩子。
下面演示了使用 Vue Router 钩子的场景,先是需要在单独的文件中注册钩子,再就是在 main.js 文件中引入注册文件,最后就是可以在 class 风格的组件中使用注册的 Vue Router 钩子
// 1. class-component-hooks.js 注册插件提供的钩子。
import Component from "vue-class-component";
Component.registerHooks(["beforeRouteEnter"]);
// 2. main.js 注册 hook
import 'class-component-hooks.js
// 3. index.vue 使用注册的钩子
import Vue from "vue";
import Component from "vue-class-component";
@Component
export default class HelloWorld extends Vue {
beforeRouteEnter(to, from, next) {
console.log("beforeRouteEnter");
next();
}
}
小结
使用 Vue-class-component 可以在 Vue2 中书写 class 风格的 Vue 组件。定义 data,书写 method,生命周期钩子函数都可以按照 class 的风格进行书写。