vue注意点$attrs、$slots
$attrs号称捡漏王
当父组件给子组件传值,子组件并没有接收数据时,此时数据在$attrs中可以拿到,并且如果子组件不需要使用数据,而孙组件需要,则可以直接v-bind="$attrs"
传给孙。
示例:
<-- 父组件 -->
<div>
<myButton type="primary"/>
<div>
<-- 子组件 -->
<el-button v-band='$attrs'>主要按钮</el-button>
这样的写法就会直接将type="primary"
传递给孙组件中,子组件不需要使用props来接收,这样写的好处是无需再子组件中定义props,属性有时候也并不确定
同样孙组件中也可以采用props来接受根组件传递过来的参数
<template>
<button></button>
</template>
<script>
export default {
inheritAttrs: false,
props: [
"type",//注意props里的参数名称不能改变,必须和根组件传递过来的是一样的
],
mounted(){
console.log(this.$attrs) //可直接使用数据或者调用根组件的方法
}
};
</script>
子组件有多个根节点时
如果子组件存在多个根节点时,需要手动绑定具体的根节点,否则就会抛出警告
这样就能解决
<template>
<div :style="$attrs['style']">我是孙组件第一个div</div>
<div>我是孙组件的第二个div</div>
</template>
<script>
inheritAttrs
inheritAttrs
的值为boolean
,默认为true,由于v-band='$attrs'
传递过来的值会作为dom元素上的属性存在,设置为false可以阻止这个行为,这些属性仍然可以通过$attrs来访问,(vue2中class和style不会受到影响,但是vue3中class和style会受影响)
-
vue2中
inheritAttrs: true
inheritAttrs: false
-
vue3中
inheritAttrs: true
inheritAttrs: false
vue3禁止inheritAttrs
如果你使用了 <script setup>
,你需要一个额外的 <script>
块来书写这个选项声明:
<script>
// 使用普通的 <script> 来声明选项
export default {
inheritAttrs: false
}
</script>
<script setup>
// ...setup 部分逻辑
</script>
vue3中访问$attrs
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
</script>
如果没有使用setup
语法糖,则
export default {
setup(props, context) {
// 透传 attribute 被暴露为 ctx.attrs
console.log(context.attrs)
}
}
$slots
$slots可以拿到父组件所传递过来的所有插槽,它是一个对象,key 名对应着插槽名。
<!-- 子组件 -->
<template>
<el-button v-bind="$attrs">
<!-- 通过遍历实现插槽透传 -->
<template v-for="(item, key, index) in $slots" :key="index" v-slot:[key]>
<slot :name="key"></slot>
</template>
</el-button>
</template>
<!-- 父组件 -->
<template>
<MyButton type="primary">
<template #default>按钮</template>
<template #icon>111</template>
<template #footer>ceshi</template>
</MyButton>
</template>
如果插槽是一个作用域插槽,传递给该插槽函数的参数可以作为插槽的 prop 提供给插槽。
<!-- 子组件 -->
<template>
<el-button v-bind="$attrs">
<!-- 通过便利实现插槽透传 -->
<!-- v-slot:[key] 绑定到对应的插槽中 -->
<template v-for="(item, key, index) in $slots" :key="index" v-slot:[key]>
<slot :name="key" v-if="key === 'icon'" :count="99"></slot>
<slot :name="key" v-else></slot>
</template>
</el-button>
</template>
<!-- 父组件 -->
<template>
<MyButton type="primary">
<template #default>按钮</template>
<template #icon="iconProps">11{{ iconProps.count }}</template>
<template #footer>ceshi</template>
</MyButton>
</template>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了