vue3 $attrs跨级emit
时间: 2023-11-16 18:47:21 浏览: 30
$attrs属性是在Vue组件中用来传递属性的对象。它允许你在父组件中将属性传递给子组件,甚至可以在多层级的组件之间传递属性。通过使用$attrs属性,你可以在子组件中访问父组件传递的属性,而无需在子组件的props中声明这些属性。
当在一个子组件中使用$attrs属性时,你可以通过触发事件(使用$emit方法)将数据传递回父组件。这样父组件就可以监听子组件触发的事件并相应地更新数据。
相关问题
$attrs和$listeners如何使用
在Vue.js中,$attrs和$listeners是两个常用的属性,它们的作用如下:
1. $attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。可以在组件中使用 $attrs 来访问这些特性,从而实现组件的透传特性。
2. $listeners:包含了父作用域中 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件,从而实现组件的透传事件。
举个例子,假设有一个父组件 Parent.vue 和一个子组件 Child.vue,Parent.vue模板代码如下:
```html
<template>
<Child
:name="name"
v-bind="$attrs"
v-on="$listeners"
/>
</template>
<script>
import Child from './Child.vue'
export default {
name: 'Parent',
components: {
Child
},
props: {
name: String
}
}
</script>
```
在这个例子中,我们通过 v-bind="$attrs" 将父组件中的所有非 props 特性(例如 id、class、style等)透传给子组件。同时,通过 v-on="$listeners" 将父组件中除了 .native 修饰器以外的所有事件监听器透传给子组件,这样就可以在子组件中使用这些事件了。
在子组件 Child.vue 中,我们可以这样使用 $attrs 和 $listeners:
```html
<template>
<div>
<input
:value="value"
@input="$emit('input', $event.target.value)"
v-bind="$attrs"
v-on="$listeners"
/>
</div>
</template>
<script>
export default {
name: 'Child',
props: {
value: String
}
}
</script>
```
在这个例子中,我们通过 v-bind="$attrs" 将父组件中的非 props 特性(例如 id、class、style等)绑定到子组件的 input 元素上,通过 v-on="$listeners" 将父组件中的事件监听器绑定到子组件的 input 元素上,这样就实现了组件的透传特性和透传事件。
在vue3中使用v-bind="$attrs"二次封装的事件如何调用
在Vue 3中,使用`v-bind="$attrs"`可以将父组件传递的非props属性传递给子组件。如果你在子组件中对这些属性进行了二次封装,你可以通过以下两种方式来调用:
1. 直接使用`$attrs`中的属性名来调用
假设你在子组件中对`click`事件进行了二次封装:
```
<template>
<button @click="handleClick">
{{ text }}
</button>
</template>
<script>
export default {
props: {
text: String,
},
methods: {
handleClick(event) {
// 二次封装的事件处理函数
this.$emit('my-click', event);
},
},
};
</script>
```
在父组件中,你可以这样使用:
```
<template>
<my-button text="Click Me" v-bind="$attrs" @my-click="handleMyClick" />
</template>
<script>
import MyButton from './MyButton.vue';
export default {
components: {
MyButton,
},
methods: {
handleMyClick(event) {
console.log('My Click Event:', event);
},
},
};
</script>
```
注意,你需要使用`@my-click`来监听`MyButton`组件中的`$emit('my-click')`事件。
2. 使用`$listeners`来调用
在Vue 3中,你还可以通过`$listeners`来访问所有父组件传递给子组件的事件监听器。你可以在子组件中使用`$listeners`来继承父组件的事件监听器,然后在组件内部进行二次封装。例如:
```
<template>
<button @click="handleClick">
{{ text }}
</button>
</template>
<script>
export default {
props: {
text: String,
},
methods: {
handleClick(event) {
// 二次封装的事件处理函数
this.$emit('my-click', event);
},
},
mounted() {
// 继承所有父组件传递的事件监听器
Object.keys(this.$listeners).forEach((eventName) => {
this.$el.addEventListener(eventName, this.$listeners[eventName]);
});
},
};
</script>
```
在父组件中,你可以这样使用:
```
<template>
<my-button text="Click Me" v-bind="$attrs" @my-click="handleMyClick" />
</template>
<script>
import MyButton from './MyButton.vue';
export default {
components: {
MyButton,
},
methods: {
handleMyClick(event) {
console.log('My Click Event:', event);
},
},
};
</script>
```
注意,你不需要使用`@my-click`来监听`MyButton`组件中的`$emit('my-click')`事件,因为`$listeners`已经继承了父组件的事件监听器。