Vue指令——$attr属性的使用方法详解

发布时间:2023-05-19

一、$attr属性简介

在Vue.js中,$attr属性是一个对象,它包含了非prop绑定的特性,即父组件传给子组件的所有属性。$attrs对象是没有响应性的,即当父组件修改属性时,子组件并不会获得更新。但是,如果使用v-bind="$attrs"$attrs绑定到子组件中,那么子组件会继承父组件的所有非prop特性,且当父组件更新这些特性时,子组件也会随之更新。

<!-- 父组件 -->
<template>
  <ChildComponent v-bind="$attrs" />
</template>
<!-- 子组件 -->
<template>
  <input v-bind="$attrs" />
</template>

二、$attr属性与$props属性的关系

在Vue.js中,$attr属性和$props属性是息息相关的。可以用$attr属性和$props属性结合,完成父组件值向子组件值的传递。 在子组件中,可以使用$props来获取通过props传递的值,使用$attrs获取通过非prop特性传递的值。如果想在子组件中获取不论是通过prop还是非prop传递的值,可以使用$props$attrs结合。

<!-- 父组件 -->
<template>
  <ChildComponent :prop1="prop1" :prop2="prop2" prop3="prop3" />
</template>
<!-- 子组件 -->
<template>
  <div>
    <p>{{ $props.prop1 }}</p>
    <p>{{ $props.prop2 }}</p>
    <p>{{ $attrs.prop3 }}</p>
    <p>{{ $attrs.class }}</p>
  </div>
</template>
<script>
  export default {
    props: {
      prop1: {
        type: String
      },
      prop2: {
        type: String
      }
    }
  }
</script>

三、使用$attr属性处理未知属性

在子组件中,如果使用v-bind="$attrs"将非prop特性绑定到子组件中时,会将父组件传递的所有未知属性都传递给子组件。对于未知属性,子组件会将其渲染成HTML特性,并且不会替换已有的特性。

<!-- 父组件 -->
<template>
  <ChildComponent title="Title" content="Content" />
</template>
<!-- 子组件 -->
<template>
  <div>
    <p>{{ $attrs.title }}</p>
    <p>{{ $attrs.content }}</p>
  </div>
</template>

四、使用$attr属性控制特性顺序

在子组件中,使用v-bind可以将$attrs属性绑定到子组件中,并控制特性的顺序。可以结合对象展开运算符与v-bind,将$attrs中的特性添加到元素的特性列表中,并控制其顺序。

<!-- 父组件 -->
<template>
  <ChildComponent class="class1" id="my-id" v-bind="$attrs" />
</template>
<!-- 子组件 -->
<template>
  <div :class="$attrs.class" :id="$attrs.id" v-bind="$attrs">
  </div>
</template>

五、$attrs属性在递归组件中的使用

在递归组件中,父组件不知道递归组件的深度,所以无法为每一层递归组件都设置一个props。在这种情况下,可以使用$attrs属性向下传递数据。

<!-- 父组件 -->
<template>
  <RecursiveComponent :level="1" class="my-class" />
</template>
<!-- 递归组件 -->
<template>
  <div :class="$attrs.class">
    <p>Level {{ $props.level }}</p>
    <RecursiveComponent :level="$props.level + 1" v-bind="$attrs" />
  </div>
</template>