带有子表单的Vue模态对话框,提交数据
Posted
技术标签:
【中文标题】带有子表单的Vue模态对话框,提交数据【英文标题】:Vue modal diaglog with child form, submit data 【发布时间】:2021-08-02 06:46:11 【问题描述】:黑色边界是模态组件,红色是具有一些表单域的组件。 按钮,保存/取消基于父模式组件。表单实际上比模态低2级(模态组件->子包装器->子表单),所以vuex感觉是更好的选择。
表单中还有一个文件选择器。
当用户单击“保存”按钮时,从组件(可能是多种表单之一)获取数据的最佳方式是什么。
选项 1 - 在每个字段更改时,调用一个方法来更新 VUEX 中的数据。 选项 1a - 更新包含整个表单的每个字段更改的对象 选项 1b - 在更改时单独更新每个字段。 选项 2 - 使用 refs 在 child 中调用某种提交方法。 选项 3 - 比 1 或 2 更好的方法!
问题
选项 1a,当我将“数据”对象传递给 vuex 时,当进行另一项更改时,表单正在更新 v-model 但它在 vuex 中,因此它在突变之外发生了突变。 选项 1b 似乎需要做很多工作才能将大量字段映射到 vuex。 选项 2 因为有 2 个级别的组件,(交换出来)参考看起来很笨重【问题讨论】:
【参考方案1】:您可以使用computed setter 来避免在突变之外发生突变。
computed:
fieldOne:
get ()
return this.$store.state.data.fieldOne
,
set (newValue)
this.$store.commit('data/fieldOne', newValue)
或者,您可以使用 :value
和 @input
代替 v-model
<input
:value="$store.state.data.fieldOne"
@input="$store.commit('data/fieldOne', $event.target.value)"
>
【讨论】:
所以这是选项1b,但是如果有20个表单字段,它可能会很长。 包装器是干什么用的? Wrapper 用于根据需要添加的内容选择正确的表单,因此 Button A 在 modal 中加载 Content A, Button B 在相同的 modal 中加载 Content B,只是孙子组件是换了 为什么不把它集成到模态组件中呢?听起来您实际上并不需要将其作为单独的组件。 无论如何,就我个人而言,当数据仅在 2 个组件(无论中间件组件)之间进行人为共享和使用时,我通常不喜欢 vuex。因此,我将在父组件中为我的表单声明一个对象,将其作为道具(父-> 子)传递,并发出任何更改(子-> 父)。我会使用上面的第二种方法(:value 和@input)。如果无法避免 Wrapper,只需使用 $attrs 和 $listeners 即可更轻松地绑定。【参考方案2】:你可以创建组件的内部对象,在 v-model 上使用他,然后点击提交按钮时更新 vuex。
【讨论】:
这就是我目前所做的。我有一个“内部”对象,它绑定到所有表单元素的 v 模型。提交按钮是层次结构中较高的两个组件,因此我仍然需要将事件单击向下传递给孙子组件,或者从孙子组件中提取数据以放入 vuex(这否定了好处) @Simon,您可以对组件使用自定义 v-model。 This link 有一个很好的教程来展示如何做到这一点。 所以自定义v-model放入wrapper,然后再放入form组件?因此完全避免使用 vuex? 是的,为了更简单,使用 mixins。 这实际上让我想到,包装器负责选择表单,因此真的应该负责用表单调用正确的方法,否则就是重复选择逻辑。所以,不用 vuex 就简化了 :)以上是关于带有子表单的Vue模态对话框,提交数据的主要内容,如果未能解决你的问题,请参考以下文章
在 SimpleModal 的模态对话框中使用 Firefox 3 中的 JQuery 和歌剧提交