选项:状态
data
返回组件实例初始响应式状态的函数。
类型
tsinterface ComponentOptions { data?( this: ComponentPublicInstance, vm: ComponentPublicInstance ): object }详细说明
该函数应返回一个普通的 JavaScript 对象,Vue 会将其变为响应式。实例创建后,可通过
this.$data访问该响应式数据对象。组件实例还会代理数据对象上的所有属性,因此this.a将等同于this.$data.a。所有顶层数据属性都必须包含在返回的数据对象中。可以向
this.$data添加新属性,但不推荐这样做。如果某个属性的期望值尚不可用,则应包含一个空值(如undefined或null)作为占位符,以确保 Vue 知道该属性存在。以
_或$开头的属性不会在组件实例上被代理,因为它们可能与 Vue 的内部属性和 API 方法冲突。你需要通过this.$data._property来访问它们。不推荐返回带有自身状态行为的对象,例如浏览器 API 对象和原型属性。返回的对象理想情况下应是一个仅表示组件状态的普通对象。
示例
jsexport default { data() { return { a: 1 } }, created() { console.log(this.a) // 1 console.log(this.$data) // { a: 1 } } }注意,如果你在
data属性中使用箭头函数,this将不会指向组件实例,但你仍然可以通过函数的第一个参数访问实例:jsdata: (vm) => ({ a: vm.myProp })另请参阅 Reactivity in Depth
props
声明组件的 props。
类型
tsinterface ComponentOptions { props?: ArrayPropsOptions | ObjectPropsOptions } type ArrayPropsOptions = string[] type ObjectPropsOptions = { [key: string]: Prop } type Prop<T = any> = PropOptions<T> | PropType<T> | null interface PropOptions<T> { type?: PropType<T> required?: boolean default?: T | ((rawProps: object) => T) validator?: (value: unknown, rawProps: object) => boolean } type PropType<T> = { new (): T } | { new (): T }[]为了便于阅读,类型已做简化。
详细说明
在 Vue 中,所有组件 props 都需要显式声明。组件 props 可以用两种形式声明:
- 使用字符串数组的简单形式
- 使用对象的完整形式,其中每个属性键是 prop 的名称,值是 prop 的类型(构造函数)或高级选项
使用基于对象的语法时,每个 prop 还可以进一步定义以下选项:
type:可以是以下原生构造函数之一:String、Number、Boolean、Array、Object、Date、Function、Symbol,以及任意自定义构造函数或它们的数组。在开发模式下,Vue 会检查 prop 的值是否匹配声明的类型,如果不匹配会抛出警告。更多详情请参见 Prop Validation。另请注意,
Boolean类型的 prop 会同时影响开发环境和生产环境中的值类型转换行为。更多详情请参见 Boolean Casting。default:当父组件未传入该 prop,或其值为undefined时,为其指定默认值。对象或数组类型的默认值必须通过工厂函数返回。该工厂函数也会接收原始 props 对象作为参数。required:定义该 prop 是否必需。在非生产环境中,如果该值为真且 prop 未传入,将会抛出控制台警告。validator:自定义验证函数,以 prop 值和 props 对象作为参数。在开发模式下,如果该函数返回假值(即验证失败),将会抛出控制台警告。
示例
简单声明:
jsexport default { props: ['size', 'myMessage'] }带验证的对象声明:
jsexport default { props: { // 类型检查 height: Number, // 类型检查加其他验证 age: { type: Number, default: 0, required: true, validator: (value) => { return value >= 0 } } } }另请参阅
computed
声明要暴露在组件实例上的计算属性。
类型
tsinterface ComponentOptions { computed?: { [key: string]: ComputedGetter<any> | WritableComputedOptions<any> } } type ComputedGetter<T> = ( this: ComponentPublicInstance, vm: ComponentPublicInstance ) => T type ComputedSetter<T> = ( this: ComponentPublicInstance, value: T ) => void type WritableComputedOptions<T> = { get: ComputedGetter<T> set: ComputedSetter<T> }详细说明
该选项接受一个对象,其中键为计算属性的名称,值可以是一个计算 getter,或一个包含
get和set方法的对象(用于可写计算属性)。所有 getter 和 setter 的
this上下文都会自动绑定到组件实例。注意,如果你在计算属性中使用箭头函数,
this将不会指向组件实例,但你仍然可以通过函数的第一个参数访问实例:jsexport default { computed: { aDouble: (vm) => vm.a * 2 } }示例
jsexport default { data() { return { a: 1 } }, computed: { // 只读 aDouble() { return this.a * 2 }, // 可写 aPlus: { get() { return this.a + 1 }, set(v) { this.a = v - 1 } } }, created() { console.log(this.aDouble) // => 2 console.log(this.aPlus) // => 2 this.aPlus = 3 console.log(this.a) // => 2 console.log(this.aDouble) // => 4 } }另请参阅
methods
声明要混入组件实例的方法。
类型
tsinterface ComponentOptions { methods?: { [key: string]: (this: ComponentPublicInstance, ...args: any[]) => any } }详细说明
已声明的方法可以直接在组件实例上访问,也可以在模板表达式中使用。所有方法的
this上下文都会自动绑定到组件实例,即使它们被传递出去也是如此。声明方法时应避免使用箭头函数,因为它们无法通过
this访问组件实例。示例
jsexport default { data() { return { a: 1 } }, methods: { plus() { this.a++ } }, created() { this.plus() console.log(this.a) // => 2 } }另请参阅 Event Handling
watch
声明在数据变化时调用的 watch 回调。
类型
tsinterface ComponentOptions { watch?: { [key: string]: WatchOptionItem | WatchOptionItem[] } } type WatchOptionItem = string | WatchCallback | ObjectWatchOptionItem type WatchCallback<T> = ( value: T, oldValue: T, onCleanup: (cleanupFn: () => void) => void ) => void type ObjectWatchOptionItem = { handler: WatchCallback | string immediate?: boolean // 默认值:false deep?: boolean // 默认值:false flush?: 'pre' | 'post' | 'sync' // 默认值:'pre' onTrack?: (event: DebuggerEvent) => void onTrigger?: (event: DebuggerEvent) => void }为了便于阅读,类型已做简化。
详细说明
watch选项期望接收一个对象,其中键是要监听的响应式组件实例属性(例如通过data或computed声明的属性),值是对应的回调函数。回调函数会接收被监听源的新值和旧值。除了根级属性外,键也可以是一个由点号分隔的简单路径,例如
a.b.c。请注意,这种用法不支持复杂表达式——只支持点号分隔的路径。如果你需要监听复杂的数据源,请改用命令式的$watch()API。值还可以是一个方法名字符串(通过
methods声明),或者一个包含额外选项的对象。使用对象语法时,回调应在handler字段下声明。附加选项包括:immediate:在 watcher 创建时立即触发回调。首次调用时旧值将为undefined。deep:如果源是对象或数组,则强制对其进行深度遍历,以便在深层变更时触发回调。参见 Deep Watchers。flush:调整回调的刷新时机。参见 Callback Flush Timing 和watchEffect()。onTrack / onTrigger:调试 watcher 的依赖。参见 Watcher Debugging。
声明 watch 回调时应避免使用箭头函数,因为它们无法通过
this访问组件实例。示例
jsexport default { data() { return { a: 1, b: 2, c: { d: 4 }, e: 5, f: 6 } }, watch: { // 监听顶层属性 a(val, oldVal) { console.log(`new: ${val}, old: ${oldVal}`) }, // 字符串形式的方法名 b: 'someMethod', // 无论被监听对象属性的嵌套深度如何,只要任意属性变化,回调都会被调用 c: { handler(val, oldVal) { console.log('c changed') }, deep: true }, // 监听单个嵌套属性: 'c.d': function (val, oldVal) { // 执行一些操作 }, // 回调会在观察开始后立即被调用 e: { handler(val, oldVal) { console.log('e changed') }, immediate: true }, // 你可以传入回调数组,它们会依次被调用 f: [ 'handle1', function handle2(val, oldVal) { console.log('handle2 triggered') }, { handler: function handle3(val, oldVal) { console.log('handle3 triggered') } /* ... */ } ] }, methods: { someMethod() { console.log('b changed') }, handle1() { console.log('handle 1 triggered') } }, created() { this.a = 3 // => new: 3, old: 1 } }另请参阅 Watchers
emits
声明组件所触发的自定义事件。
类型
tsinterface ComponentOptions { emits?: ArrayEmitsOptions | ObjectEmitsOptions } type ArrayEmitsOptions = string[] type ObjectEmitsOptions = { [key: string]: EmitValidator | null } type EmitValidator = (...args: unknown[]) => boolean详情
触发的事件可以用两种形式声明:
- 使用字符串数组的简单形式
- 使用对象的完整形式,其中每个属性键是事件名,值要么是
null,要么是一个验证函数。
验证函数会接收传递给组件
$emit调用的额外参数。例如,如果调用了this.$emit('foo', 1),那么foo对应的验证器将接收参数1。验证函数应返回一个布尔值,用于表示事件参数是否有效。请注意,
emits选项影响的是哪些事件监听器会被视为组件事件监听器,而不是原生 DOM 事件监听器。已声明事件的监听器会从组件的$attrs对象中移除,因此不会透传到组件的根元素。更多细节请参见 透传 Attributes。示例
数组语法:
jsexport default { emits: ['check'], created() { this.$emit('check') } }对象语法:
jsexport default { emits: { // 无需校验 click: null, // 带校验 submit: (payload) => { if (payload.email && payload.password) { return true } else { console.warn(`无效的 submit 事件负载!`) return false } } } }另请参阅
expose
当组件实例通过模板 ref 被父组件访问时,声明要暴露的公共属性。
类型
tsinterface ComponentOptions { expose?: string[] }详情
默认情况下,当通过
$parent、$root或模板 ref 访问组件实例时,组件会向父组件暴露所有实例属性。这可能并不理想,因为组件通常会包含应保持私有的内部状态或方法,以避免过度耦合。expose选项接受一个属性名字符串列表。使用expose时,只有显式列出的属性才会暴露在组件的公共实例上。expose只影响用户自定义属性——它不会过滤掉内置的组件实例属性。示例
jsexport default { // 只有 `publicMethod` 会在公共实例上可用 expose: ['publicMethod'], methods: { publicMethod() { // ... }, privateMethod() { // ... } } }