Vue3 中的 @Options,是做什么的?
@Options 其实是实现 “类风格组件” 的装饰器。有了它,就可以用定义类的语法来定义一个 Vue 组件。
Vue3 中的 @Options,是做什么的?
@Options 是个啥?
@Options 是 Vue Class Component (8.x版) 提供的一个装饰器 (Decorator),目的是使 Vue 开发者可以用 类语法 的风格来定义组件 (Class-Style Component)。 也就是说,以前是通过传入选项来定义一个组件的,现在通过 @Options,可以把组件当作一个类,用定义类的语法来定义组件。
补充说明:
-
在进行 Vue + TypeScript 开发时,Class-Style Component 是一个可选项,开发者如果不习惯这种风格,可以不使用它;
-
@Options 由 Vue Class Component (7.x版) 中的 @Component 改名而来。
为什么我的项目中会有 @Options 或 @Component?
当用 Vue CLI 创建项目时,如果采用手动模式,并选中了 TypeScript,在之后弹出的 Use class-style component syntax?(Y/n)
中,回复 y,则启用了 Class Style 的组件风格。
因此,如果开发者还是喜欢用选项来定义组件,而且是自己主导的项目,可以在项目创建时禁用它,或者删掉相关依赖再 npm install
- Vue3 项目中,相关依赖是
vue-class-component
,以及 tsconfig.json 中的experimentalDecorators
选项 (如果有用到装饰器,也可不删); - Vue2 项目中,相关依赖是
vue-class-component
及vue-property-decorator
。
啥是“类语法风格的组件”(Class-Style Component)?
简单说,就是用定义类的语法来定义组件,具体而言:
- data 数据可以声明为类属性
- methods 可以声明为类成员方法
- computed 属性可以声明为类属性访问器 (getter/setter)
- hooks 及 data(), render() 可以声明为类成员方法,但无法从外部访问(且约定这些命名为保留字,应避免用作自定义方法的命名)
- 对于其它选项,直接放在 @Options 的参数中(如果没有需要放到 @Options 中的参数,那么 @Options 可以省略)
举个栗子 (采用 Vue3 + TypeScript ):
//Vue原生的选项风格:
import { defineComponent } from 'vue';
import MyComponent from './MyComponent.vue';
export default defineComponent ({
name: 'App',
components: {
MyComponent
},
data(){ return {
count: 0
}},
mounted(){ this.count = 10 },
methods:{
increase(){ this.count++; }
},
computed:{
doubleCount():number{ return this.count * 2; }
}
})
//改用类风格写法:
import { Options, Vue } from 'vue-class-component';
import MyComponent from './MyComponent.vue';
@Options({
components: {
MyComponent
}
})
export default class App extends Vue {
count = 0 //注意不能为 undefined,否则该数据的响应性将失效
mounted(){ this.count = 10 }
increase(){ this.count++; }
get doubleCount():number{ return this.count * 2; }
}
Vue Class Component 更多有趣特性
- 自定义装饰器 (例如定义 @Log 实现日志记录,guide/custom-decorators)
- 以类的方式实现组件继承与混合 (guide/extend-and-mixins)
- Hooks Auto-complete (guide/hooks-auto-complete)
- 对组合式 API 的支持 (v8, issue#416)
- 类风格的 props (v8, issue#465)
@Options 与 @Component 的一点区别
Vue Class Component 从 8.x 开始支持 Vue3,并且将 @Component 更名为 @Options。(issue#406)
此外,还允许省略 @Options,并且项目中只需要依赖 vue-class-component
一个库。
Summary
- @Component will be renamed to @Options.
- @Options is optional if you don’t declare any options with it.
- Vue constructor is provided from vue-class-component package.
…
这也是为什么创建 Vue 2 项目时看到的是 @Component,而创建 Vue3 项目时看到的是 @Options。
虽然只是改个名,但它们的意义却不一样了:
- 旧版的 @Component 不能省略,它的意义是标注一个类是 Class-Style Component;
- 新版中,只要一个类继承了来自
vue-class-component
库的Vue
,就是一个 Class-Style Component,无须任何装饰器来标注。@Options 的意义更像是专门用来放置像 component、emits、mixins 这种声明性、资源引用性的非核心逻辑的内容。
在使用原生的选项风格来定义组件时,Vue 官方推荐我们按照统一的顺序来组织选项,以提升代码的可读性 ( 风格指南 / 组件-实例选项的顺序推荐),而使用 Class-Style Component 时,借助 @Options,可以进一步将这种规范落地——依赖、组合、接口等选项在 @Options 中完成声明,组合式 API、本地状态、watch、声明周期勾子、methods、render 等承载组件核心逻辑的内容放在类中定义。
开发中的注意事项
- 类属性的初始值不能为 undefined,否则该属性的响应性将失效 (you can use null value or use data hook instead);
- 不要在类中定义构造函数,建议在 created 勾子中完成想在构造器中完成的初始化功能 (always use lifecycle hooks instead of constructor)。
参考资料:
[1] Vue Class Component Github主页 (前往)
[2] 官方文档 (本文发布时仅更新到 v7) (前往)
[3] v8 proposals in the issue list (前往)
更多推荐
所有评论(0)