[Vue] $attrs的使用场景

正常情况下,Vue推荐用props向子组件参数。但是在特定场景下,使用$attrs 会更方便。

考虑最简单的场景,一个滑动输入框组件定义如下:

<template>
  <input 
    class="slider__input"
    type="range" 
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)" />
</template>

<script>
export default {
  name: "Slider",
  props: {
    modelValue: [Number, String]
  }
};
</script>

正常调用它的方式为:

 <Slider v-model="value" />

但实际上,我们可以为其额外增加一些属性

    <Slider v-model="value"  
      min="0"
      max="50"
      class="blue_slider"
      id="special_id"
      data-cy="cypress-slider"
      @keydown="() => true"
      aria-label="Example slider"/>

这些属性没有在子组件的props 中,会以原生方式出现在input标签中:

属性绑定成功,注意在Vue 3.x里,class也能正常传递

由于这里根元素只有一个<input>,不需要$attrs 登场,就能完成属性的传递。

如果input不是根元素呢?

例如父组件不变,子组件换成这样定义:

<template>
  <h1>{{ title }}</h1>
  <input 
    type="range" 
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
    class="slider__input" />
  <div>Value: {{ value }}</div>
</template>

渲染出来的dom如下:

不是根节点,属性无法绑定

可以看出,我们额外增加的属性并没有传递给input.

好了,轮到$attrs 登场了

只需给input增加一个指令 v-bind="$attrs"

<template>
  <h1>{{ title }}</h1>
  <input 
    type="range" 
    **v-bind="$attrs"**
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
    class="slider__input" />
  <div>Value: {{ value }}</div>
</template>    

利用`v-bind="$attrs"` 实现属性绑定

可以看出,额外增加的属性,又成功的传递给了input标签。

总结

  1. Vue 3.x中所有的属性,包括class/style都可以通过$attrs 传递,这个与Vue2.x不同.

  2. v-bind="$attrs" 指令,能够指定dom节点,完成属性绑定。

  3. $attrs 只适合传递原生属性/事件,其它的属性还是老老实实用propsevents传递吧。

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):