vue $attrs和$listeners

vue2

  • $attrs: 接收父组件传过来的属性($props)
 <!-- 接收父组件传过来的属性并传递给子组件 -->
<a-upload
    name="file"
    v-bind="$attrs"
    :file-list="fileList"
  >
  </a-upload>
  • $listeners: 接收父组件传递过来的方法
    $listeners传方法的同时自己添加事件,两个回调都会执行
<!-- 接收父组件传过来的方法并传递给子组件 -->
<Table
   ref="pageTable"
   v-on="listeners"
   @on-row-dblclick="rowdblclick"
 >
 </Table>
  • $props: 接收父组件传过来并且已经定义的属性
<!-- 接收父组件传过来的属性并传递给子组件,包含已定义和未定义的所有属性 -->
 <Table
     ref="pageTable"
     v-bind="{...$props,...$attrs}"
     v-on="listeners"
     @on-row-dblclick="rowdblclick"
      >
</Table>
<script>
export default {
props: {
    tableTitle: {
      type: Object,
      default: () => ({}),
    },
    columns: {
      type: Array,
      required: true,
    }, // 表头数据
  },
}
</script>

vue3

vue3把attrs和attrs和attrslisteners统一合并到$attrs中,其他和vue一样

### Vue2与Vue3中 `$attrs` `$listeners` 的区别 #### 1. **Vue2中的 `$attrs` `$listeners`** 在 Vue2 中,`$attrs` 是指父组件传递下来的所有属性(不包括 `class`、`style` 已经被声明为 `props` 的属性)。这些属性可以通过 `v-bind="$attrs"` 转递给子组件[^5]。 另一方面,`$listeners` 则是一个对象,包含了当前作用域内的所有事件监听器。开发者可以使用 `v-on="$listeners"` 将这些事件转发给子组件[^5]。 需要注意的是,在 Vue2 中,如果希望阻止某些属性或事件被自动继承到根元素,则需要设置 `inheritAttrs: false`[^4]。 #### 2. **Vue3中的 `$attrs` 变化** 到了 Vue3,设计发生了显著变化。`$listeners` 已经被废弃,其功能完全融入了 `$attrs` 对象之中。这意味着 `$attrs` 不仅包含未声明的属性,还涵盖了所有的事件监听器[^2]。因此,在 Vue3 中不再需要单独处理 `$listeners`,而是统一通过 `v-bind="$attrs"` 同时绑定属性事件监听器。 此外,由于 `$listeners` 的移除,Vue3 提供了一种更简洁的方式来管理事件属性的传播[^1]。 --- ### Vue3虚拟DOM静态标记的时机 在 Vue3 中,当生成虚拟 DOM 节点时,会对其进行优化分析。对于那些不会动态更新的部分(即所谓的“静态节点”),框架会在初始化阶段打上特定标志位以便后续跳过不必要的比较操作[^1]。这种机制有助于提升渲染性能,尤其是在复杂场景下能够减少大量无意义的工作量。 具体来说,静态标记发生在以下几个时刻: - 当解析模板字符串构建 AST 抽象语法树期间; - 或者是在手动创建 VNode 实例过程中由内部逻辑完成此判断过程。 这一改进使得即使面对大规模应用也能保持较高的运行效率。 --- ### 示例代码对比 以下是基于上述理论的一个简单实现案例: #### Vue2 版本 ```html <!-- ParentComponent.vue --> <template> <ChildComponent foo="bar" @custom-event="handleCustomEvent"></ChildComponent> </template> <script> export default { methods: { handleCustomEvent() { console.log('Custom event triggered!'); } } }; </script> <!-- ChildComponent.vue --> <template> <div> <!-- Props and events are passed down manually --> <GrandchildComponent v-bind="$attrs" v-on="$listeners"></GrandchildComponent> </div> </template> <script> export default { inheritAttrs: false, }; </script> ``` #### Vue3 版本 ```html <!-- ParentComponent.vue --> <template> <ChildComponent foo="bar" @custom-event="handleCustomEvent"></ChildComponent> </template> <script> import { defineComponent } from 'vue'; export default defineComponent({ setup() { const handleCustomEvent = () => { console.log('Custom event triggered!'); }; return { handleCustomEvent }; }, }); </script> <!-- ChildComponent.vue --> <template> <div> <!-- Both attributes and listeners are forwarded using $attrs --> <GrandchildComponent v-bind="$attrs"></GrandchildComponent> </div> </template> <script> export default { inheritAttrs: false, }; </script> ``` --- ### 总结 综上所述,Vue3 对于 `$attrs` `$listeners` 的整合简化了开发流程,并提高了 API 的一致性;与此同时,通过对虚拟 DOM 进行静态标记进一步增强了框架的整体表现力。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值