渲染时监听事件
FormCreate 支持将表单内部事件抛出到业务组件中,让您可以在业务组件代码中监听和处理这些事件的业务逻辑。这种方式实现了表单与业务逻辑的解耦,使表单更加灵活和可维护。
抛出事件
在表单事件中,通过 api.emit() 方法可以抛出自定义事件,将事件传递到业务组件中。
避免与内置事件重名
请避免使用 FormCreate 的内置事件名称作为自定义事件名,否则可能会与内置事件冲突。
常见的内置事件包括:
submit- 表单提交事件change- 表单数据变化事件update:modelValue- 表单数据更新事件mounted- 表单挂载完成事件created- 表单创建完成事件validateFail- 验证失败事件
建议:使用有意义的自定义事件名,如 formSubmit、fieldChange、dataLoaded 等,避免与内置事件冲突。
1. 在按钮点击事件中抛出事件:
js
{
type: 'button',
field: 'submitBtn',
title: '提交',
on: {
click: function($inject) {
//确保获取到最外层表单的 API
const api = $inject.api.top;
// 获取表单数据
const formData = api.formData();
// 抛出提交事件,传递表单数据
api.emit('formSubmit', formData);
}
}
}2. 在字段变化时抛出事件:
js
{
type: 'input',
field: 'username',
title: '用户名',
on: {
change: function($inject) {
//确保获取到最外层表单的 API
const api = $inject.api.top;
const value = $inject.args[0];
// 抛出字段变化事件
api.emit('fieldChange', {
field: 'username',
value: value
});
}
}
}通过标签方式监听
在渲染表单时,可以通过 Vue 的事件监听语法 @事件名 来监听表单抛出的事件,并在业务组件中处理业务逻辑。
1. 监听表单提交事件:
vue
<template>
<form-create
v-model="formData"
v-model:api="fApi"
:rule="rule"
@formSubmit="handleFormSubmit"
/>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
const formData = ref({});
const fApi = ref(null);
const rule = ref([
{
type: 'button',
field: 'submitBtn',
title: '提交',
on: {
click: function($inject) {
const api = $inject.api;
api.emit('formSubmit', api.formData());
}
}
}
]);
// 处理表单提交
async function handleFormSubmit(formData) {
try {
const response = await axios.post('/api/submit', formData);
console.log('提交成功:', response.data);
// 显示成功消息
if (fApi.value && fApi.value.message) {
fApi.value.message('提交成功', 'success');
}
} catch (error) {
console.error('提交失败:', error);
// 显示错误消息
if (fApi.value && fApi.value.message) {
fApi.value.message('提交失败', 'error');
}
}
}
</script>2. 监听字段变化事件:
vue
<template>
<form-create
v-model="formData"
v-model:api="fApi"
:rule="rule"
@fieldChange="handleFieldChange"
/>
</template>
<script setup>
import { ref } from 'vue';
const formData = ref({});
const fApi = ref(null);
const rule = ref([
{
type: 'input',
field: 'username',
title: '用户名',
on: {
change: function($inject) {
const api = $inject.api;
api.emit('fieldChange', {
field: 'username',
value: $inject.args[0]
});
}
}
}
]);
// 处理字段变化
function handleFieldChange({ field, value }) {
console.log(`字段 ${field} 变化为:`, value);
// 根据字段变化执行业务逻辑
if (field === 'username') {
// 检查用户名是否可用
checkUsernameAvailability(value);
}
}
function checkUsernameAvailability(username) {
// 业务逻辑:检查用户名是否可用
console.log('检查用户名:', username);
}
</script>3. 监听多个事件:
vue
<template>
<form-create
v-model="formData"
v-model:api="fApi"
:rule="rule"
@formSubmit="handleFormSubmit"
@formValidate="handleFormValidate"
@dataLoaded="handleDataLoaded"
@dataLoadError="handleDataLoadError"
/>
</template>
<script setup>
import { ref } from 'vue';
const formData = ref({});
const fApi = ref(null);
const rule = ref([
// 表单规则
]);
// 处理表单提交
function handleFormSubmit(formData) {
console.log('表单提交:', formData);
// 业务逻辑
}
// 处理表单验证
function handleFormValidate({ valid }) {
console.log('验证结果:', valid);
// 业务逻辑
}
// 处理数据加载完成
function handleDataLoaded({ field, data }) {
console.log(`字段 ${field} 数据加载完成:`, data);
// 业务逻辑
}
// 处理数据加载错误
function handleDataLoadError({ field, error }) {
console.error(`字段 ${field} 数据加载失败:`, error);
// 错误处理逻辑
}
</script>通过API方式监听
在获取到 API 对象后,可以通过 api.bus.$on() 方法动态监听事件,这种方式更加灵活,可以在组件的任何生命周期中注册事件监听器。
vue
<template>
<form-create
v-model="formData"
v-model:api="fApi"
:rule="rule"
/>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
const formData = ref({});
const fApi = ref(null);
const rule = ref([
{
type: 'button',
field: 'submitBtn',
title: '提交',
on: {
click: function($inject) {
$inject.api.emit('formSubmit', $inject.api.formData());
}
}
}
]);
// 事件处理函数
function handleFormSubmit(formData) {
console.log('表单提交:', formData);
// 处理业务逻辑
}
// 组件挂载时注册监听
onMounted(() => {
if (fApi.value) {
fApi.value.on('formSubmit', handleFormSubmit);
}
});
// 组件卸载前移除监听(可选)
onBeforeUnmount(() => {
if (fApi.value) {
fApi.value.off('formSubmit', handleFormSubmit);
}
});
</script>注意事项
重要提示
- 避免与内置事件重名:请勿使用 FormCreate 的内置事件名称(如
submit、change、update:modelValue、mounted、created等)作为自定义事件名,否则会与内置事件冲突,导致不可预期的行为 - 事件名称:事件名称是字符串,建议使用有意义的命名,如
formSubmit、fieldChange、dataLoaded等,使用驼峰命名法 - 事件参数:
api.emit()可以传递多个参数,这些参数会传递给事件处理函数 - 监听时机:使用
api.bus.$on()时,确保 API 对象已经初始化,建议在watch或onMounted中注册 - 内存泄漏:如果使用
api.bus.$on()注册监听器,建议在组件卸载时使用api.bus.$off()移除监听器,避免内存泄漏 - 两种方式的选择:
- 模板事件监听:适合在组件模板中直接声明,代码更清晰,Vue 会自动处理清理
- API 方法监听:适合动态注册和移除,更灵活,但需要手动管理


