`emits` 是 Vue 3 中用于显式声明组件可以触发哪些事件的选项。它的作用是让组件的使用者清楚地知道组件会触发哪些事件,同时也可以用于验证事件的有效性。
### `emits` 的用法
#### 1. **简单用法(数组形式)**
如果只是声明组件会触发哪些事件,可以使用数组形式:
```javascript
export default {
emits: ['update:modelValue', 'submit'],
methods: {
handleClick() {
// 触发一个事件
this.$emit('submit', { data: 'some data' });
}
}
};
```
- 在这个例子中,组件声明了会触发两个事件:`update:modelValue` 和 `submit`。
- 使用 `this.$emit('事件名', 参数)` 来触发事件。
#### 2. **验证事件(对象形式)**
如果需要对事件进行验证,可以使用对象形式。每个事件名对应一个验证函数:
```javascript
export default {
emits: {
// 验证 submit 事件
submit: (payload) => {
if (payload && payload.data) {
return true; // 验证通过
} else {
console.warn('Invalid payload for submit event!');
return false; // 验证失败
}
}
},
methods: {
handleClick() {
// 触发 submit 事件
this.$emit('submit', { data: 'some data' });
}
}
};
```
- 在这个例子中,`submit` 事件会验证传递的参数是否符合要求。
- 如果验证函数返回 `false`,Vue 会在开发环境下发出警告。
#### 3. **父子组件通信**
`emits` 通常用于父子组件通信。父组件监听子组件触发的事件,子组件通过 `$emit` 触发事件并传递数据。
**子组件(ChildComponent.vue)**:
```javascript
export default {
emits: ['update:modelValue'],
methods: {
updateValue(newValue) {
// 触发事件并传递数据
this.$emit('update:modelValue', newValue);
}
}
};
```
**父组件(ParentComponent.vue)**:
```vue
<template>
<ChildComponent @update:modelValue="handleUpdate" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleUpdate(newValue) {
console.log('Received new value:', newValue);
}
}
};
</script>
```
- 子组件通过 `$emit` 触发 `update:modelValue` 事件,并传递数据。
- 父组件通过 `@update:modelValue` 监听事件,并处理数据。
#### 4. **与 `v-model` 结合**
`emits` 常用于实现自定义组件的 `v-model` 功能。Vue 3 中,`v-model` 默认使用 `modelValue` 作为 prop,`update:modelValue` 作为事件。
**子组件(CustomInput.vue)**:
```vue
<template>
<input :value="modelValue" @input="handleInput" />
</template>
<script>
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
methods: {
handleInput(event) {
// 触发事件并传递输入框的值
this.$emit('update:modelValue', event.target.value);
}
}
};
</script>
```
**父组件(ParentComponent.vue)**:
```vue
<template>
<CustomInput v-model="inputValue" />
</template>
<script>
import CustomInput from './CustomInput.vue';
export default {
components: {
CustomInput
},
data() {
return {
inputValue: ''
};
}
};
</script>
```
- 子组件通过 `$emit('update:modelValue')` 实现双向绑定。
- 父组件通过 `v-model` 绑定数据。
### 总结
- `emits` 用于声明组件可以触发的事件。
- 可以通过数组形式简单声明,也可以通过对象形式对事件进行验证。
- 常用于父子组件通信和实现自定义 `v-model` 功能。
- 使用 `this.$emit('事件名', 参数)` 触发事件并传递数据。