Attributes透传
理解:就是组件上传值,组件接收时候没有用props接收,这就是透传,比如class类名或id以及style等都是透传因为没有在props声明,如果在组件上绑定是事件v-on监听器,没有在组件中使用emits声明也是透传
Attributes透传其实也是继承,在组件上绑定的类名,组件中的根元素可以继承组件中绑定的类名
示例(了解)一般不会在外面使用类名
没有使用props接收就是透传
father.vue
<template>
<!-- 给son组件传值却没有在son组件中使用props声明就是透传
这个类名最终会绑定到son组件根标签中<el-button class='mybtn'></el-button> 注意只会绑定到根标签-->
<son class='mybtn'></son>
</template>
<script setup>
import son from './son'
</script>
son.vue
<template>
<el-button>点击</el-button>
</template>
<script setup>
</script>
注意:子组件中的根标签有类名,子组件根标签还是可以继承子组件绑定的类名
实例2
father.vue
<template>
son组件上绑定事件在son组件中没有使用emits声明这个事件就是透传,将会把事件绑定到son组件中的根标签,点击son组件根标签就会触发son组件上绑定事件(因为绑定的是click事件如果是别的事件就不会触发了比如@fn='fnBtn')
<son @click='myBtn'></son>
</template>
<script setup>
import son from './son'
let myBtn = () =>{
console.log(111)
}
</script>
son.vue
<template>
<button>点击</button>
</template>
<script setup>
</script>
注意:son组件根标签有自己的绑定事件,son组件上绑定一个事件,son组件根标签有自己事件也会继承son组件上绑定事件,点击son组件根标签会触发自己事件也会触发son组件上绑定的事件
注意:组件上传值,还是绑定事件,如果组件内部没有使用props接收和使用emit触发事件都是透传,传递的值和事件都会放到组件中的根标签,换句话说组件根标签继承了组件上传递的属性与事件,如果事件不是click点击根标签没什么反应
禁用 Attributes 继承
理解:单个组件中禁用当前组件透传过来的属性和事件,也就是禁止当前组件继承不让放到根标签中,在当前组件中禁用掉
export default(选项式)写法
<script>
export default{
inheritAttrs: false // 当前组件中禁用继承
setup(){
}
}
</script>
script setup(组合式)写法(需要额外增加一个script选项式写法)
<script>
export default{
inheritAttrs: false // 当前组件中禁用继承
}
</script>
<script setup>
</script>
Vue3通过使用Attributes 透传实现跨组件传值和事件传值
父子组件之间透传不使用props接收值以及emits事件传值
father.vue
<template>
<son str='这是son组件' @fn='fnBtn'></son>
</template>
<script setup>
import son from './son'
let fnBtn = () =>{
console.log('进行打印')
}
</script>
son.vue
<template>
son组件上传递过来的属性以及定义的事件没有使用props接收以及没有使用emits触发事件都是透传,都会放到组件根标签上,如果事件不是@click以及其它鼠标经过离开等事件,点击根标签不会触发事件的比如@fn='fnBtn'自定义事件点击根标签不会触发此事件需要使用attrs调用
<!-- 是一个响应式对象 -->
<span>{{$attrs}}</span>
</template>
<script setup>
import {useattrs} from 'vue'
let attrs = useattrs()
// 获取组件透传过来的属性以及事件
console.log(attrs) // 打印的是一个proxy响应式对象,包含透传过来的属性与事件
</script>
深层次传值以及事件传值
father.vue
<template>
<son str='这是son组件' @fn='fnBtn'></son>
</template>
<script setup>
import son from 'vue'
let fnBtn = () =>{
console.log('进行打印')
}
</script>
son.vue
<template>
<div>
// v-bind就是动态绑定属性,$attrs透视透传过来的属性与事件,$attrs是一个对象通过vue解析之后child组件进行传值与绑定事件
<child v-bind='$attrs'></child>
</div>
</template>
<script setup>
import child from 'vue'
import {useattrs} from 'vue'
let attrs = useattrs()
console.log(attrs)
</script>
child.vue
<template>
</template>
<script setup>
import {useattrs} from 'vue'
let attrs = useattrs()
console.log(attrs)
attrs.onFn() // 触发最外面组件绑定的事件,也可以进行传值操作
</script>
上面是组合式写法,选项式写法如下
child.vue
<template>
$attrs获取当前组件透传的传值与事件
<span>{{$attrs}}<span>
</template>
<script>
export default {
setup(props,ctx){
console.log(ctx.attrs) // 透传过来的属性和事件,是一个proxy响应式对象
}
}
</script>
注意:组件上传值与绑定事件没有使用props与emits就是透传会放到组件中的根标签如果这个根标签是一个组件的话,会放到这个组件上进行传值与绑定事件(就可以不用使用v-bind=‘$attrs’)