Vue 中 props 和 attrs 概念与区别

本文深入解析Vue中Props与Attrs的区别与应用,探讨如何在父组件向子组件传递属性时,合理使用Props与Attrs,确保代码清晰与高效。同时,讲解如何控制属性继承与自定义属性的管理。

Vue 中的区别:
Vue中的 a t t r s 和 attrs和 attrslistener
Vue-- a t t r s 与 attrs与 attrslisteners的详解

在 vue 中,对于在父组件中传递的属性,

若在子组件中使用@Prop声明了属性如@Prop name,则 name 属性只会在 this. p r o p s 中 出 现 , 不 会 出 现 在 t h i s . props 中出现,不会出现在 this. propsthis.attrs 中;

若在子组件中没有使用@Prop声明属性,则属性会默认在 this. a t t r s 中 , 不 会 出 现 在 t h i s . attrs 中,不会出现在 this. attrsthis.props 中;

故一般用 this.$attrs 接收处理没有用 @Prop 声明的属性,但一般不推荐这样,尽量使用 @Prop 声明所有自定义的属性,便于管理。

在 html 中的区别:
HTML中的attribute属性和JavaScript中的property属性的详解以及区别

props 是父类向子类传递并且需要子类主动接收的属性;

attrs 默认是父类传递到子类根元素的属性,子类不用主动接收,会直接放在子类根元素上。

而 attrs 的这种默认行为,可以通过设置 inheritAttrs 到 false,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例属性 a t t r s 可 以 让 这 些 特 性 生 效 , 且 可 以 通 过 v − b i n d ( v − b i n d = " attrs 可以让这些特性生效,且可以通过 v-bind (v-bind=" attrsvbindvbind="attrs")显性的绑定到非根元素上。

<think>嗯,用户问的是Vue2的$attrsVue3的$attrs的用法区别。我需要先回忆一下这两个版本中attrs的行为有什么不同。 首先,Vue2中的$attrs包含了父作用域中不作为prop被识别(且获取)的特性绑定(classstyle除外)。也就是说,如果子组件没有在props里声明某个属性,这个属性就会出现在$attrs里。在Vue2中,当子组件使用v-bind="$attrs"时,这些属性会应用到子组件的根元素上。但是,如果子组件的根元素已经有了相同的属性,父组件传过来的值会覆盖子组件本身的属性。不过,在Vue2里,如果子组件里嵌套了另一个组件,就需要手动通过v-bind="$attrs"传递下去,否则属性不会自动传递到更深层的子组件。 然后是Vue3的变化。Vue3中的$attrs现在包含了所有传递给组件的属性,包括classstyle。这点Vue2不同,Vue2是排除这两个的。另外,Vue3在继承父组件传递的属性时,如果子组件的根元素已经有相同的属性,父组件的属性会子组件的合并,而不是覆盖。比如,父组件传了一个class="parent-class",子组件根元素有class="child-class",结果会是两者的合并。这在Vue2里是不会发生的,Vue2里父组件的会覆盖子组件的。 还有,Vue3中的v-bind="$attrs"现在会将所有属性(包括事件监听器)传递到子组件,而Vue2中事件监听器是在$listeners里的,需要单独处理。Vue3把$listeners移除了,合并到了$attrs里,这样在传递时更方便,不需要同时绑定$attrs$listeners。 另外,在Vue3中,如果组件有多个根节点(Fragment特性),需要显式绑定$attrs,否则会有警告。而Vue2中组件只能有一个根节点,所以自动应用到根元素上没问题,但Vue3允许多个根节点,这时候就需要开发者自己决定在哪里绑定$attrs。 举个例子,比如在Vue2中,子组件接收父组件的placeholder属性,但如果没有声明为prop,就会在$attrs里,然后通过v-bind="$attrs"传递给input元素。而在Vue3中,同样的情况,但class也会被包含,并且如果子组件有多个根节点,必须手动绑定,否则不会自动应用。 可能用户在使用Vue2升级到Vue3时遇到了问题,比如样式不合并或者事件监听器失效,这时候需要了解$attrs的变化。用户可能需要知道如何正确传递属性处理多个根节点的情况,以及为什么在Vue3中classstyle会被包含在$attrs里。 总结一下,Vue3的$attrs更全面,包含所有属性,合并行为改变,事件监听器合并到attrs,以及多根组件需要显式绑定。这些区别需要详细说明,帮助用户避免迁移中的常见问题。</think>好的!我将从**用法对比****核心区别**两个方面,帮你梳理 Vue2 Vue3 中 `$attrs` 的异同。 --- ### 一、基础概念 `$attrs` 是 Vue 用于接收**父组件传递的非 prop 属性**的容器(例如 `class`、`style`、原生事件等)。它在组件层级嵌套时,常用于透传属性。 --- ### 二、Vue2 中的 `$attrs` #### 1. 特性 - **排除已声明的 props**:父组件传递的属性若未被 `props` 接收,则进入 `$attrs` - **不包含 `class` `style`**:这两者会被单独提取到组件根元素上 - **需要手动透传**:若要将属性传递给更深层子组件,需显式使用 `v-bind="$attrs"` #### 2. 代码示例 ```html <!-- 父组件 --> <ChildComponent id="parent-id" class="parent-class" data-test="123" /> <!-- 子组件 (ChildComponent.vue) --> <template> <div> <GrandChild v-bind="$attrs" /> </div> </template> <script> export default { // 未声明 props: ['dataTest'] } </script> ``` - `$attrs` 内容:`{ id: "parent-id", data-test: "123" }` - `class="parent-class"` 自动附加到子组件根元素 `<div>` --- ### 三、Vue3 中的 `$attrs` #### 1. 核心变化 - **包含 `class` `style`**:不再自动附加到根元素,而是进入 `$attrs` - **合并代替覆盖**:若子组件根元素已有同名属性,Vue3 会**合并值**而非覆盖 - **移除 `$listeners`**:事件监听器合并到 `$attrs` 中(如 `@click`) - **多根节点需显式绑定**:若组件有多个根元素,需手动指定 `$attrs` 位置 #### 2. 代码示例 ```html <!-- 父组件 --> <ChildComponent id="parent-id" class="parent-class" @click="handleClick" /> <!-- 子组件 (ChildComponent.vue) --> <template> <div :class="$attrs.class"> <GrandChild v-bind="$attrs" /> </div> </template> <script> export default { // 需要手动处理 class } </script> ``` - `$attrs` 内容:`{ id: "parent-id", class: "parent-class", onClick: handleClick }` --- ### 四、关键区别总结 | **特性** | **Vue2** | **Vue3** | |-------------------------|-----------------------------------|-----------------------------------| | `class` & `style` | 不包含在 `$attrs`,自动附加根元素 | 包含在 `$attrs`,需手动处理 | | 同名属性处理 | 父级覆盖子级 | 合并父级子级的值 | | 事件监听器 | 存放在 `$listeners` | 合并到 `$attrs` 中 | | 多根组件 | 不支持多根组件 | 必须显式指定 `v-bind="$attrs"` | --- ### 五、使用建议 1. **Vue2 迁移到 Vue3**: - 检查 `class` `style` 是否被正确处理 - 替换 `$listeners` 为 `$attrs` 2. **透传第三方组件**: ```html <!-- Vue3 中透传所有属性事件 --> <template> <ThirdPartyComponent v-bind="$attrs" /> </template> ``` 3. **合并根元素属性**: ```html <!-- 合并父级自身的 class --> <div :class="[localClass, $attrs.class]"></div> ``` --- 理解这些差异能帮助你更精准地控制组件间的属性传递!如果有具体场景问题,可以进一步探讨。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值