跳转到内容

选项:状态

data

一个返回组件实例初始响应式状态的函数。

  • 类型

    ts
    interface ComponentOptions {
      data?(
        this: ComponentPublicInstance,
        vm: ComponentPublicInstance
      ): object
    }
  • 详情

    该函数预期返回一个普通的 JavaScript 对象,Vue 将将其变为响应式。实例创建后,可以访问响应式数据对象为 this.$data。组件实例还代理了数据对象上找到的所有属性,因此 this.a 等同于 this.$data.a

    所有顶级数据属性都必须包含在返回的数据对象中。向 this.$data 添加新属性是可能的,但不推荐。如果属性的期望值尚未可用,则应包含空值,例如 undefinednull,以确保 Vue 知道属性存在。

    _$ 开头的属性将不会在组件实例上代理,因为它们可能与 Vue 的内部属性和 API 方法冲突。您必须通过 this.$data._property 来访问它们。

    不推荐返回具有自身状态行为的对象,如浏览器 API 对象和原型属性。返回的对象应理想地是一个仅表示组件状态的普通对象。

  • 示例

    js
    export default {
      data() {
        return { a: 1 }
      },
      created() {
        console.log(this.a) // 1
        console.log(this.$data) // { a: 1 }
      }
    }

    注意,如果使用具有 data 属性的箭头函数,则 this 不会是组件的实例,但您仍然可以通过函数的第一个参数访问实例

    js
    data: (vm) => ({ a: vm.myProp })
  • 另请参阅 深入响应式原理

props

声明组件的 props。

  • 类型

    ts
    interface 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:可以是以下原生构造函数之一:StringNumberBooleanArrayObjectDateFunctionSymbol、任何自定义构造函数或这些的数组。在开发模式下,Vue 将检查 prop 的值是否与声明的类型匹配,如果不匹配,将抛出警告。有关详细信息,请参阅 Prop 验证

      请注意,具有 Boolean 类型的 prop 会影响其在开发和生产环境中的值转换行为。有关更多详细信息,请参阅 布尔转换

    • default:指定当父组件未传递或具有 undefined 值时 prop 的默认值。对象或数组默认值必须通过工厂函数返回。工厂函数还将接收原始 prop 对象作为参数。

    • required:定义 prop 是否必需。在非生产环境中,如果此值为真且未传递 prop,将抛出控制台警告。

    • validator:自定义验证函数,它只接受 prop 值作为参数。在开发模式中,如果此函数返回一个假值(即验证失败),将抛出控制台警告。

  • 示例

    简单声明

    js
    export default {
      props: ['size', 'myMessage']
    }

    具有验证的对象声明

    js
    export default {
      props: {
        // type check
        height: Number,
        // type check plus other validations
        age: {
          type: Number,
          default: 0,
          required: true,
          validator: (value) => {
            return value >= 0
          }
        }
      }
    }
  • 另请参阅

computed

声明要暴露在组件实例上的计算属性。

  • 类型

    ts
    interface 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>
    }
  • 详情

    此选项接受一个对象,其中键是计算属性的名称,值是计算获取器或具有 getset 方法的对象(对于可写计算属性)。

    所有获取器和设置器都自动将它们的 this 上下文绑定到组件实例。

    请注意,如果您使用箭头函数与计算属性一起使用,则 this 不会指向组件实例,但您仍然可以通过函数的第一个参数访问实例。

    js
    export default {
      computed: {
        aDouble: (vm) => vm.a * 2
      }
    }
  • 示例

    js
    export default {
      data() {
        return { a: 1 }
      },
      computed: {
        // readonly
        aDouble() {
          return this.a * 2
        },
        // writable
        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

声明要混合到组件实例中的方法。

  • 类型

    ts
    interface ComponentOptions {
      methods?: {
        [key: string]: (this: ComponentPublicInstance, ...args: any[]) => any
      }
    }
  • 详情

    声明的可以在组件实例上直接访问的方法,或在模板表达式中使用。所有方法都自动将它们的 this 上下文绑定到组件实例,即使在传递时也是如此。

    在声明方法时避免使用箭头函数,因为它们无法通过 this 访问组件实例。

  • 示例

    js
    export default {
      data() {
        return { a: 1 }
      },
      methods: {
        plus() {
          this.a++
        }
      },
      created() {
        this.plus()
        console.log(this.a) // => 2
      }
    }
  • 另请参阅 事件处理

watch

声明在数据更改时调用的监视回调。

  • 类型

    ts
    interface 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 // default: false
      deep?: boolean // default: false
      flush?: 'pre' | 'post' | 'sync' // default: 'pre'
      onTrack?: (event: DebuggerEvent) => void
      onTrigger?: (event: DebuggerEvent) => void
    }

    类型简化以提高可读性。

  • 详情

    watch 选项期望一个对象,其中键是要监视的响应式组件实例属性(例如通过 datacomputed 声明的属性)——值是相应的回调。回调接收监视源的旧值和新值。

    除了根级属性之外,键还可以是一个简单的点分隔路径,例如 a.b.c。请注意,此用法不支持复杂表达式——只支持点分隔路径。如果您需要监视复杂数据源,请使用命令式 $watch() API。

    值还可以是方法名(通过 methods 声明)的字符串,或包含附加选项的对象。当使用对象语法时,回调应在 handler 字段下声明。附加选项包括

    • immediate:在创建监视器时立即触发回调。第一次调用时旧值将是 undefined
    • deep:如果源是对象或数组,强制深度遍历,以便在深度突变时触发回调。请参阅 深度监视器
    • flush:调整回调的刷新时间。请参阅 回调刷新时间watchEffect()
    • onTrack / onTrigger:调试监视器的依赖项。请参阅 监视器调试

    在声明监视回调时避免使用箭头函数,因为它们将无法通过 this 访问组件实例。

  • 示例

    js
    export default {
      data() {
        return {
          a: 1,
          b: 2,
          c: {
            d: 4
          },
          e: 5,
          f: 6
        }
      },
      watch: {
        // watching top-level property
        a(val, oldVal) {
          console.log(`new: ${val}, old: ${oldVal}`)
        },
        // string method name
        b: 'someMethod',
        // the callback will be called whenever any of the watched object properties change regardless of their nested depth
        c: {
          handler(val, oldVal) {
            console.log('c changed')
          },
          deep: true
        },
        // watching a single nested property:
        'c.d': function (val, oldVal) {
          // do something
        },
        // the callback will be called immediately after the start of the observation
        e: {
          handler(val, oldVal) {
            console.log('e changed')
          },
          immediate: true
        },
        // you can pass array of callbacks, they will be called one-by-one
        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
      }
    }
  • 另请参阅 监视器

emit

声明组件发出的自定义事件。

  • 类型

    ts
    interface 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 对象中删除,因此它们不会传递到组件的根元素。有关更多详细信息,请参阅 穿透属性

  • 示例

    数组语法

    js
    export default {
      emits: ['check'],
      created() {
        this.$emit('check')
      }
    }

    对象语法

    js
    export default {
      emits: {
        // no validation
        click: null,
    
        // with validation
        submit: (payload) => {
          if (payload.email && payload.password) {
            return true
          } else {
            console.warn(`Invalid submit event payload!`)
            return false
          }
        }
      }
    }
  • 另请参阅

expose

当组件实例通过模板引用由父组件访问时,声明公开的公共属性。

  • 类型

    ts
    interface ComponentOptions {
      expose?: string[]
    }
  • 详情

    默认情况下,当通过 $parent$root 或模板引用访问组件实例时,组件实例会公开所有实例属性。这可能是不希望的,因为组件很可能有内部状态或方法,应该保持私有以避免紧密耦合。

    expose 选项期望一个属性名称字符串列表。当使用 expose 时,只有明确列出的属性将在组件的公共实例上公开。

    expose 只影响用户定义的属性 - 它不会过滤掉内置组件实例属性。

  • 示例

    js
    export default {
      // only `publicMethod` will be available on the public instance
      expose: ['publicMethod'],
      methods: {
        publicMethod() {
          // ...
        },
        privateMethod() {
          // ...
        }
      }
    }
选项:状态已加载