import { defineComponent, provide, ref, VNode } from 'vue' import { useCustomEvent, EmitEvent } from '../../helpers/useNVueEvent' import { uniFormKey, UniFormCtx, UniFormFieldCtx } from '../../components/form' const NATIVE_COMPONENTS = ['u-input', 'u-textarea'] export default defineComponent({ name: 'Form', emits: ['submit', 'reset'], setup({}, { slots, emit }) { const rootRef = ref(null) const trigger = useCustomEvent>(rootRef, emit) const fields: UniFormFieldCtx[] = [] let resetNative: Function provide(uniFormKey, { addField(field: UniFormFieldCtx) { fields.push(field) }, removeField(field: UniFormFieldCtx) { fields.splice(fields.indexOf(field), 1) }, submit(evt: Event) { // 获取原生组件值 let outFormData: any = {} resetNative && resetNative(outFormData) let formData = fields.reduce((res, field) => { if (field.submit) { const [name, value] = field.submit() name && (res[name] = value) } return res }, Object.create(null)) Object.assign(outFormData, formData) trigger('submit', { value: outFormData, }) }, reset(evt: Event) { // 清空原生组件值 resetNative && resetNative() fields.forEach((field) => field.reset && field.reset()) trigger('reset', evt) }, }) return () => { const vnodes = slots.default && slots.default() resetNative = useResetNative(vnodes) return {vnodes} } }, }) function useResetNative(children?: VNode[]) { const modulePlus = weex.requireModule('plus') const getOrClearNativeValue = (outResult: any, nodes?: VNode[]): void => { ;(nodes || children || []).forEach(function (node: VNode) { if ( NATIVE_COMPONENTS.indexOf(String(node.type)) >= 0 && node.el && node.el.attr && node.el.attr.name ) { if (outResult) { outResult[node.el.attr.name] = modulePlus.getValue(node.el.nodeId) } else { node.el.setValue('') } } if ( Array.isArray(node.children) && node.children && node.children.length ) { getOrClearNativeValue(outResult, node.children as VNode[]) } }) } return getOrClearNativeValue }