Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] form 组件如何实现 change 事件? #12486

Closed
shiyl962 opened this issue Dec 5, 2023 · 10 comments
Closed

[Feature Request] form 组件如何实现 change 事件? #12486

shiyl962 opened this issue Dec 5, 2023 · 10 comments

Comments

@shiyl962
Copy link

shiyl962 commented Dec 5, 2023

这个功能解决了什么问题?

如题,需要表单的任一子组件在其值被修改时,引发form事件,应该怎么实现呢?请多指教!

你期望的 API 是什么样子的?

<van-form @change="xxx" ... >
...

@shiyl962
Copy link
Author

shiyl962 commented Dec 6, 2023

技术支持出来一下,没人理吗

@chouchouji
Copy link
Contributor

我觉得你可以监听子组件的值,通过form实例来触发下一步操作,比如说 validate

@shiyl962
Copy link
Author

shiyl962 commented Dec 7, 2023

我觉得你可以监听子组件的值,通过form实例来触发下一步操作,比如说 validate

谢谢回复!我的理解是,子组件都去绑定@change@update:modelValue到一个处理函数对吗,但这样要多写代码,有点麻烦。官方不能在form组件中解决一下吗

@chouchouji
Copy link
Contributor

我觉得直接加 change 并不会降低 你说的代码量 ,change事件 要加的话,要提供 previousValue 和 currentValue,对比差异,这些成本 不小的。自己用watch 去监听值的修改,表单整体不是很庞大的话,逻辑划分更清楚,也更容易维护。如果过于庞大,可能要考虑是不是适合移动端了。

@shiyl962
Copy link
Author

shiyl962 commented Dec 7, 2023

再次感谢 @chouchouji ,想到过用watch,由于不了解watch背后的资源开销情况,故未用。
这两天尝试了修改源码,把form的children 放出来了,并试图用代码绑定change,但都没有成功。代码如下:

refForm.value.children.reduce<Record<string, unknown>>((form, field) => {
       field.change = (e) => { listenFieldChange(field, e) }
        //field.$emitter.on('change', listenFieldChange)
      console.log('onMounted children =>', form, field, field.name)
    }, {});

@chouchouji
Copy link
Contributor

再次感谢 @chouchouji ,想到过用watch,由于不了解watch背后的资源开销情况,故未用。 这两天尝试了修改源码,把form的children 放出来了,并试图用代码绑定change,但都没有成功。代码如下:

refForm.value.children.reduce<Record<string, unknown>>((form, field) => {
       field.change = (e) => { listenFieldChange(field, e) }
        //field.$emitter.on('change', listenFieldChange)
      console.log('onMounted children =>', form, field, field.name)
    }, {});

我觉得可以考虑用 watch
image

@chouchouji
Copy link
Contributor

再次感谢 @chouchouji ,想到过用watch,由于不了解watch背后的资源开销情况,故未用。 这两天尝试了修改源码,把form的children 放出来了,并试图用代码绑定change,但都没有成功。代码如下:

refForm.value.children.reduce<Record<string, unknown>>((form, field) => {
       field.change = (e) => { listenFieldChange(field, e) }
        //field.$emitter.on('change', listenFieldChange)
      console.log('onMounted children =>', form, field, field.name)
    }, {});

应该先获取所有的children,遍历监听 child 的 onUpdate:xxx 或者 值修改触发的事件 ,通过 useExpose 导出
image

@shiyl962
Copy link
Author

shiyl962 commented Dec 7, 2023

@chouchouji 哈哈哈太感谢了!!!按您的意见,用 watch 已经可以实现了,代码如下:

const formFields = []
// 以下测试 vant form children
refForm.value.children.reduce<Record<string, unknown>>((form, field) => {
  //field.blur = (e) => { listenFieldEvent(field, e) }
  //field.$emitter.on('blur', listenFieldEvent)
  formFields.push(field.formValue)
  console.log('onMounted children =>', form, field)
}, {});

watch(formFields, () => {
  console.log('form change =>', refForm.value.getValues())
})

我再用您后边的办法试一试

@chouchouji
Copy link
Contributor

@chouchouji 哈哈哈太感谢了!!!按您的意见,用 watch 已经可以实现了,代码如下:

const formFields = []
// 以下测试 vant form children
refForm.value.children.reduce<Record<string, unknown>>((form, field) => {
  //field.blur = (e) => { listenFieldEvent(field, e) }
  //field.$emitter.on('blur', listenFieldEvent)
  formFields.push(field.formValue)
  console.log('onMounted children =>', form, field)
}, {});

watch(formFields, () => {
  console.log('form change =>', refForm.value.getValues())
})

我再用您后边的办法试一试

@chouchouji 哈哈哈太感谢了!!!按您的意见,用 watch 已经可以实现了,代码如下:

const formFields = []
// 以下测试 vant form children
refForm.value.children.reduce<Record<string, unknown>>((form, field) => {
  //field.blur = (e) => { listenFieldEvent(field, e) }
  //field.$emitter.on('blur', listenFieldEvent)
  formFields.push(field.formValue)
  console.log('onMounted children =>', form, field)
}, {});

watch(formFields, () => {
  console.log('form change =>', refForm.value.getValues())
})

我再用您后边的办法试一试

我写的只是一个思路,没有具体验证过(不用太放心上

@Canoe-kong
Copy link

结合阁下的思路,再结合vue3中watchEffect允许我们自动跟踪回调的响应式依赖的原理,
const formFields = ref([]); watchEffect(async () => { if (formRef.value) { formFields.value = formRef.value?.getValues(); console.log('formFields', formFields.value); } });
这个当表单change的时候也会被触发

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants