属性透传
- 传递给子组件时,没有被子组件消费的属性或事件,常见的如id、class
注意1
- 1.class、style是合并的,style中如果出现重复的样式,以透传属性为准
- 2.id属性是以透传属性为准,其他情况透传属性名相同,取值以透传属性为准
APP.vue
<template>
<div>
<A style="color: red" id="first" class="app"></A>
</div>
</template>
A组件
<template>
<div id="second" class="a" style="color:blue; border: 1px solid gray;">
<h2>A</h2>
</div>
</template>
最终html
<div id="first" class="a app" style="color: red; border: 1px solid gray;"><h2>A</h2></div>
注意2
- 1.多个根节点的时候,可以为需要使用透传属性的根节点绑定v-bind=“$attrs”,来确定透传属性的归属
APP.vue
<template>
<div>
<A style="color: red" id="first" class="app"></A>
</div>
</template>
A组件
<template>
<div >
<h2>A1</h2>
</div>
<div v-bind="$attrs">
<h2>A2</h2>
</div>
</template>
最终html
<div>
<div>
<h2>A1</h2>
</div>
<div id="first" class="app" style="color: red;">
<h2>A2</h2>
</div>
</div>
注意3
- 1.多层透传,可以通过defineOptions({inheritAttrs:false})来实现
- 2.透传属性使用:
- 模板中可以直接使用$attrs.id 这种方式
- 在js中如果在setup语法糖中,可以用useAttrs
- js中非
<script setup>
import { useAttrs } from 'vue';
const aa = useAttrs()
console.log(aa) //aa是一个proxy对象,在子组件中不能修改
</script>
APP.vue
<template>
<div>
<A style="color: red" id="first" class="app"></A>
</div>
</template>
A组件
<template>
<div id="second">
<h2>A</h2>
<B v-bind="$attrs"></B>
</div>
</template>
<script setup>
import B from "./B.vue"
import {defineOptions} from 'vue'
defineOptions({
inheritAttrs:false
})
</script>
B组件
<template>
<div>
<h5>B</h5>
<p>{{ $attrs.id }}</p>
</div>
</template>
最终html
<div>
<div id="second">
<h2>A</h2>
<div id="first" class="app" style="color: red;">
<h5>B</h5>
<p>first</p>
</div>
</div>
</div>
注入
- 为了解决参数逐层传递问题
注意
- 1.上层组件作为提供方,下层组件使用,比如父组件是提供方,子组件使用;也可以提供全局属性
- 2.provide 和 inject 方法需要在 setup 方法中同步调用
- 3.修改provide属性的方式最好放在提供方,统一修改
- 4.注入时,可以提供一个默认值,如果没有该属性的提供方,返回的为默认值
- 5.provide的数据可以为任意类型,inject后不会改变数据类型
- 6.可以通过Symbol 来避免注入名冲突
APP.vue
<template>
<div>
<A></A>
</div>
</template>
<script setup>
import {ref,provide} from 'vue'
import A from "./components/A.vue"
const first = ref("first")
const num = ref(1)
function updateFirst(val){
first.value = val
}
provide("first",{
first,
updateFirst
})
provide("num",num)
</script>
A组件
<template>
<div>
<h2>A</h2>
<B></B>
</div>
</template>
<script setup>
import { provide, reactive } from "vue";
import B from "./B.vue"
const obj = reactive({
name:"zhangsan"
})
provide("obj",obj)
</script>
B组件
<template>
<div style="border: 1px solid gray;">
<h5>B</h5>
<p>first:{{ first}}</p>
<p><button @click="updateFirst('inject first')">change first</button></p>
<p>默认值:{{ defaultTest }}</p>
<hr/>
<p>
num:{{ num }}--{{ typeof num }}
</p>
<p>num+1: {{ num+1 }}</p>
</div>
</template>
<script setup>
import { inject } from 'vue';
const {first,updateFirst} = inject("first")
console.log("first:",first)
const defaultTest = inject('defaultTest',"test 默认值")
//ref 数值
const num = inject("num")
//reactive
const obj = inject("obj")
console.log(obj)
</script>