在vue3中的$attrs的变化

$listeners已被删除合并到$attrs中。$attrs现在包括class和style属性。也就是说在vue3中$listeners不存在了。vue2中$listeners是单独存在的。在vue3 $attrs包括class和style属性, vue2中 $attrs 不包含class和style属性。

在vue2中的$attrs

在Vue 2中,attrs里面包含着上层组件传递的所有数据(除style和class)当一个组件声明了prop时候,attrs里面包含除去prop里面的数据剩下的数据。结合inheritAttrs:false,可以将传递下来的数据应用于其他元素,而不是根元素:

父组件的属性直接渲染在根节点上

父页面.vue

    
import TestCom from "../../components/TestCom.vue"

子组件.vue

    

我是p标签

我是span

我们发现父组件中的属性直接是渲染在了 
这个节点上。变为了
。因为在默认情况下,父组件的属性会直接渲染在子组件的根节点上。【重点】然后有些情况我们希望是渲染在指定的节点上。那怎么处理这问题呢?我们的 $attrs 和 inheritAttrs: false 这一对 ”好基友“ 闪亮登场

如何让父组件的属性渲染在指定的节点上

我们可以使用 $attrs 配合 inheritAttrs: false 可以将属性渲染在指定的节点上子组件的代码中新增 inheritAttrs: false//子组件    

我是p标签

我是span // 不让子组件的根节点渲染属性inheritAttrs: false

发现问题-根节点和指定节点都别渲染了属性

好家伙,你不是说  $attrs 配合 inheritAttrs: false可以将属性渲染在指定的节点上。现在虽然渲染在指定节点上。但是根节点也有。这样不好吧。切。走了。走了。菜鸡。这,这,这, 你别走呀。 等一会。赶紧偷偷人偷偷去官网看一下出怎么说的。原来是这样的: 可以和普通的  一起使用。普通的  在有这些情况下或许会被使用到。比如:无法在  中的声明选项中去使用 inheritAttrs 或插件的自定义选项。

我们需要将代码变为如下:

    

我是p标签

我是span //无法在 中的声明选项中去使用 inheritAttrs。//所有只有在整一个export default { inheritAttrs: false, customOptions: {}} 你的代码

TMD 又又发现问题了

在浏览器中提示:[plugin:vite:vue] [@vue/compiler-sfc]  and  must have the same language type.TMD 又又发现问题了。稳住,我可以的。在心里一直告诉自己,冷静点,我可以解决这个问题的。先看看它提示  must have the same language type. 必须具有相同的语言类型小问题就是说必须要有一个类型。我将  script 上添加一个 lang="ts"就解决了。 我感觉自己又行了。    

我是p标签

我是span export default { inheritAttrs: false, customOptions: {}}

简单的介绍 $listeners

$listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。我的理解:因为$listeners 可以接收父级组件中(不含.native修饰器的) v-on 事件监听器.所以在进行组件事件传递的时候非常有用。很多时候我们对组件进行二次封装的时候不可能将组件中的内置事件都抛出来。这个时候 $listeners 就派上用场了。在vue2中有 vue2中$listeners是单独存在的。vue3 被合并到$attrs中了。

vue2中 v-bind=”$attrs” 和 $listeners

//子组件.vue    
点击打开 这是一段信息 取 消 确 定 export default { inheritAttrs: false, //不让属性直接渲染在根节点上 data() { return { dialogVisible: false }; }, methods: { handleClose(done) { this.$confirm('确认关闭?').then(() => { done(); }).catch(() => { }); } }};

//父组件.vue  
import LianCom from "../components/LianCom.vue"export default { components: { LianCom }, methods: { openHandler() { console.log('可以直接注册事件,因为 v-on="$listeners"会接收除了.native的原生事件') } }}

vue3 v-bind=”$attrs” 会接收属性和事件

//子组件     打开            
我值弹窗中的内容 export default { inheritAttrs: false,}import { ref } from 'vue'const dialogTableVisible = ref(false)ps:我们没有向上抛出任何事件。但是父组件可以调用 Element Plus 中对话框中的内置方法。但是父页面中可以 注册 Element Plus 中对话框中的内置方法。
// 父组件    
import { ElMessageBox } from 'element-plus'import TestCom from "../../components/TestCom.vue"// Dialog 关闭的回调const closeHandler = () => { console.log('Dialog 关闭的回调')}/* before - close 只会在用户点击关闭按钮或者对话框的遮罩区域时被调用。如果你在 footer 具名插槽里添加了用于关闭 Dialog 的按钮,那么可以在按钮的点击回调函数里加入 before - close 的相关逻辑。关闭前的回调,会暂停 Dialog 的关闭. 回调函数内执行 done 参数方法的时候才是真正关闭对话框的时候.*/const beforeclose = (done: () => void) => { ElMessageBox.confirm('Are you sure to close this dialog?') .then(() => { console.log('用户点击了确定') done() }) .catch(() => { console.log('用户点击了取消') })}

遇见问题,这是你成长的机会,如果你能够解决,这就是收获。 作者:晚来南风晚相识
出处:https://www.cnblogs.com/IwishIcould/

想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,或者关注博主,在此感谢!

万水千山总是情,打赏5毛买辣条行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主(っ•̀ω•́)っ✎⁾⁾!

想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

支付宝微信 本文版权归作者所有,欢迎转载,未经作者同意须保留此段声明,在文章页面明显位置给出原文连接
如果文中有什么错误,欢迎指出。以免更多的人被误导。