百科狗-知识改变命运!
--

状态选项 ​

是丫丫呀2年前 (2023-11-21)阅读数 30#技术干货
文章标签组件

状态选项 ​

data ​

用于声明组件初始响应式状态的函数。

  • 类型

    ts
    interface 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 原生对象或是带原型的类实例等。理想情况下,返回的对象应是一个纯粹代表组件状态的普通对象。

  • 示例

    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 = PropOptions | PropType | null
    
    interface PropOptions {
      type?: PropType
      required?: boolean
      default?: T | ((rawProps: object) => T)
      validator?: (value: unknown) => boolean
    }
    
    type PropType = { new (): T } | { new (): T }[]

    为了便于阅读,对类型进行了简化。

  • 详细信息

    状态选项 ​

    在 Vue 中,所有的组件 props 都需要被显式声明。组件 props 可以通过两种方式声明:

    • 使用字符串数组的简易形式。
    • 使用对象的完整形式。该对象的每个属性键是对应 prop 的名称,值则是该 prop 应具有的类型的构造函数,或是更高级的选项。

    在基于对象的语法中,每个 prop 可以进一步定义如下选项:

    • type:可以是下列原生构造函数之一:StringNumberBooleanArrayObjectDateFunctionSymbol、任何自定义构造函数,或由上述内容组成的数组。在开发模式中,Vue 会检查一个 prop 的值是否匹配其声明的类型,如果不匹配则会抛出警告。详见 Prop 校验。

      还要注意,一个Boolean类型的 prop 会影响它在开发或生产模式下的值转换行为。详见 Boolean 类型转换。

    • default:为该 prop 指定一个当其没有被传入或值为undefined时的默认值。对象或数组的默认值必须从一个工厂函数返回。工厂函数也接收原始 prop 对象作为参数。

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

    • validator:将 prop 值作为唯一参数传入的自定义验证函数。在开发模式下,如果该函数返回一个假值 (即验证失败),一个控制台警告将会被抛出。

  • 示例

    简易声明:

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

    对象声明,带有验证:

    js
    export default {
      props: {
        // 类型检查
        height: Number,
        // 类型检查 + 其他验证
        age: {
          type: Number,
          default: 0,
          required: true,
          validator: (value) => {
            return value >= 0
          }
        }
      }
    }
  • 参考

    • 指南 - Props
    • 指南 - 为组件的 props 标注类型

computed ​

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

  • 类型

    ts
    interface ComponentOptions {
      computed?: {
        [key: string]: ComputedGetter | WritableComputedOptions
      }
    }
    
    type ComputedGetter = (
      this: ComponentPublicInstance,
      vm: ComponentPublicInstance
    ) => T
    
    type ComputedSetter = (
      this: ComponentPublicInstance,
      value: T
    ) => void
    
    type WritableComputedOptions = {
      get: ComputedGetter
      set: ComputedSetter
    }
  • 详细信息

    该选项接收一个对象,其中键是计算属性的名称,值是一个计算属性 getter,或一个具有getset方法的对象 (用于声明可写的计算属性)。

    所有的 getters 和 setters 会将它们的this上下文自动绑定为组件实例。

    注意,如果你为一个计算属性使用了箭头函数,则this不会指向该组件实例,不过你仍然可以通过该函数的第一个参数来访问实例:

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

    js
    export 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 ​

用于声明要混入到组件实例中的方法。

  • 类型

    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 = (
      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: {
        // 侦听根级属性
        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) {
          // do something
        },
        // 该回调将会在侦听开始之后立即调用
        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
      }
    }
  • 参考侦听器

emits ​

用于声明由组件触发的自定义事件。

  • 类型

    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对象中移除。详见透传 Attributes。

  • 示例

    数组语法:

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

    对象语法:

    js
    export default {
      emits: {
        // 没有验证函数
        click: null,
    
        // 具有验证函数
        submit: (payload) => {
          if (payload.email && payload.password) {
            return true
          } else {
            console.warn(`Invalid submit event payload!`)
            return false
          }
        }
      }
    }
  • 参考

    • 指南 - 透传 Attributes
    • 指南 - 为组件的 emits 标注类型

expose ​

用于声明当组件实例被父组件通过模板引用访问时暴露的公共属性。

  • 类型

    ts
    interface ComponentOptions {
      expose?: string[]
    }
  • 详细信息

    默认情况下,当通过$parent$root或模板引用访问时,组件实例将向父组件暴露所有的实例属性。这可能不是我们希望看到的,因为组件很可能拥有一些应保持私有的内部状态或方法,以避免紧耦合。

    expose选项值应当是一个包含要暴露的属性名称字符串的数组。当使用expose时,只有显式列出的属性将在组件实例上暴露。

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

  • 示例

    js
    export default {
      // 只有 `publicMethod` 在公共实例上可用
      expose: ['publicMethod'],
      methods: {
        publicMethod() {
          // ...
        },
        privateMethod() {
          // ...
        }
      }
    }

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)
最新文章